我有一个对象数组,我想对其进行迭代以生成一个新的过滤数组。同时,我还需要根据参数从新数组中过滤出一些对象。我试着这样做:

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

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


当前回答

你可以使用数组。Reduce带有箭头的函数是一行代码

Const选项= [ {name: 'One', assigned: true}, {name: 'Two',赋值:false}, {name: 'Three',赋值:true}, ]; Const reduced = options。Reduce ((result, option) =>选项。分配?结果。concat({name: option.name, newProperty: 'Foo'}): result, []); . getelementbyid(“输出”)。innerHTML = JSON.stringify(简化); <h1>仅分配选项</h1> <pre id="output"> </pre> .

其他回答

同时执行filter + map的最有效方法是将数据作为泛型可迭代对象处理,并同时执行这两件事。在这种情况下,您最多只需要浏览一次数据。

下面的例子是使用iter-ops库,并做到了这一点:

import {pipe, filter, map} from 'iter-ops';

const i = pipe(
    inputArray,
    filter(value => value === 123), // filter on whatever key you want
    map(value => /* any mapping here*/) // remap data as you like
);

// i = iterable that can be processed further;

console.log([...i]); //=> list of new objects

上面,我说的是最多,因为如果你对iterable结果应用进一步的逻辑,比如限制映射项的数量,例如,你最终会迭代对象列表甚至少于一次:

const i = pipe(
    inputArray,
    filter(value => value === 123), // filter on whatever key you want
    map(value => /* any mapping here*/), // remap as you like
    take(10) // take up to 10 items only
);

在上面,我们进一步限制迭代,一旦生成了10个结果项就停止,因此我们对数据的迭代少于一次。这是最有效的了。

更新

我被要求补充为什么这种解决方案比减少更有效,所以就是这样……

数组的约简是一个有限的操作,它遍历完整的数据集,以产生结果。因此,当您需要对输出数据进行进一步处理时,您将最终生成一个新的迭代序列,等等。

当您有一个复杂的业务逻辑要应用到一个序列/可迭代对象时,将该逻辑链接起来总是更有效的,而只遍历序列一次。在许多情况下,您最终会对一个序列进行复杂的处理,甚至一次都不遍历完整的数据集。这就是可迭代数据处理的效率。

附注:我是上述图书馆的作者。

在某些情况下,使用forEach不是更容易(或同样容易)吗

Var选项= [ {name: 'One', assigned: true}, {name: 'Two',赋值:false}, {name: 'Three',赋值:true}, ]; Var减小= [] options.forEach(功能(选项){ If (option.assigned) { var someenewvalue = {name: option.name, newProperty: 'Foo'} reduced.push (someNewValue); } }); . getelementbyid(“输出”)。innerHTML = JSON.stringify(简化); <h1>仅分配选项</h1> <pre id="output"> </pre> .

但是,如果有一个malter()或fap()函数组合映射和过滤器函数就更好了。它将像过滤器一样工作,除了返回true或false之外,它将返回任何对象或null/undefined。

你应该使用Array。减少这个。

Var选项= [ {name: 'One', assigned: true}, {name: 'Two',赋值:false}, {name: 'Three',赋值:true}, ]; Var减少=选项。减少(函数(筛选,选项){ If (option.assigned) { var someenewvalue = {name: option.name, newProperty: 'Foo'} filtered.push (someNewValue); } 返回过滤; },[]); . getelementbyid(“输出”)。innerHTML = JSON.stringify(简化); <h1>仅分配选项</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;
}, []);

使用Array.prototype.filter:

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

你可以使用数组。Reduce带有箭头的函数是一行代码

Const选项= [ {name: 'One', assigned: true}, {name: 'Two',赋值:false}, {name: 'Three',赋值:true}, ]; Const reduced = options。Reduce ((result, option) =>选项。分配?结果。concat({name: option.name, newProperty: 'Foo'}): result, []); . getelementbyid(“输出”)。innerHTML = JSON.stringify(简化); <h1>仅分配选项</h1> <pre id="output"> </pre> .