同时映射和过滤数组

2022-08-30 00:22:44

我有一个对象数组,我想循环访问它们以生成一个新的筛选数组。但是,我需要根据参数从新数组中过滤掉一些对象。我正在尝试这个:

function renderOptions(options) {
    return options.map(function (option) {
        if (!option.assigned) {
            return (someNewObject);
        }
    });   
}

这是一个好方法吗?有没有更好的方法?我愿意使用任何库,如lodash。


答案 1

为此,您应该使用 Array.reduce

var options = [
  { name: 'One', assigned: true }, 
  { name: 'Two', assigned: false }, 
  { name: 'Three', assigned: true }, 
];

var reduced = options.reduce(function(filtered, option) {
  if (option.assigned) {
     var someNewValue = { name: option.name, newProperty: 'Foo' }
     filtered.push(someNewValue);
  }
  return filtered;
}, []);

document.getElementById('output').innerHTML = JSON.stringify(reduced);
<h1>Only assigned options</h1>
<pre id="output"> </pre>

或者,减速器可以是纯功能,就像这样

var reduced = options.reduce(function(result, option) {
  if (option.assigned) {
    return result.concat({
      name: option.name,
      newProperty: 'Foo'
    });
  }
  return result;
}, []);

答案 2

自2019年以来,Array.prototype.flatMap是不错的选择。

options.flatMap(o => o.assigned ? [o.name] : []);

从上面链接的MDN页面:

flatMap可以用作在映射期间添加和移除项目(修改项目数)的一种方式。换句话说,它允许您将许多项目映射到许多项目(通过单独处理每个输入项目),而不是总是一对一。从这个意义上说,它的工作方式与过滤器相反。只需返回一个 1 元素数组来保留项目,返回一个多元素数组来添加项目,或者返回一个 0 元素数组来删除项目。