【问题标题】:Using Reduce instead of chaining Filter and Map使用 Reduce 而不是链接过滤器和映射
【发布时间】:2020-01-02 04:57:48
【问题描述】:

我有一个函数接受一个狗对象数组并返回一个包含所有所有者姓名的数组。

    dogs = [
      {name: 'Archie', breed: 'Lurcher', owner: 'Jack'},
      {name: 'Charlie', breed: 'Pug', owner: 'John'},
      {name: 'Buddy', breed: 'Pug', owner: 'Mike'}
    ]

我通过链接过滤器和映射得到结果,但这意味着我在同一个列表上循环了两次。我知道这可以使用 Reduce 来完成,但不确定我将如何做到这一点。很多关于 Reduce 的例子似乎都带有数字,当我试图解决我的问题时,这有点令人困惑。

任何帮助将不胜感激。谢谢

function getOwners(dogs) {

   return dogs.filter(dog => dog.breed === 'Pug').map(dog => dog.owner);
}

  returns ['John', 'Mike']

【问题讨论】:

    标签: javascript reduce


    【解决方案1】:

    你要找的功能是:

    dogs.reduce((total, current) => current.breed === "Pug" ? [...total, current.owner] : total, []);
    

    我们检查狗并为每个元素测试current.breed === "Pug",如果是真的,我们将当前狗的所有者添加到total 数组中,否则我们保持整个数组不变。

    【讨论】:

    • 使用 concat 而不是传播以提高效率:total.concat(current.owner) : total。
    【解决方案2】:

    您传递一个初始数组,并且在减少的同时仅在该值未被过滤掉的情况下推送映射的值。

    const filteredMap = (filter, mapping) => {
      return arr => Array.prototype.reduce.call(arr, (accumulator, value) => {
        if (filter(value)) accumulator.push(mapping(value));
        return accumulator;
      }, []);
    };
    
    const getOwners = filteredMap(dog => dog.breed == 'Pug', dog => dog.owner);
    
    getOwners([
      {name: 'Archie', breed: 'Lurcher', owner: 'Jack'},
      {name: 'Charlie', breed: 'Pug', owner: 'John'},
      {name: 'Buddy', breed: 'Pug', owner: 'Mike'}
    ]);  // => [ 'John', 'Mike' ]
    

    把它写成一个循环可能会更清楚:

    const filteredMap = (filter, mapping) => {
      return arr => {
        const res = [];
        for (const value of arr) {
            if (filter(value)) res.push(mapping(value));
        }
        return res;
      };
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-10
      • 2020-05-07
      • 2020-10-11
      • 2017-12-09
      • 2017-08-23
      相关资源
      最近更新 更多