Array.prototype.reduce的实际用途是什么?

时间:2016-04-14 06:14:44

标签: javascript

据我所知,这是一种具有广泛适用性的常用功能。 example on Mozilla Development Network

[0, 1, 2, 3, 4].reduce(function(previousValue, currentValue, currentIndex, array) {
  return previousValue + currentValue;
});

具有对值进行求和的效果。当然,这不是一个很好的例子,因为他们不能做到[0, 1, 2, 3, 4].sum().

那么现实生活中的情况是什么,作为网络开发者,我将面临一个问题并思考," 啊,这是reduce的工作!"要么是一个非常模糊的情况,要么是一个常见的情况,我可以使用reduce作为解决它的聪明方法。

3 个答案:

答案 0 :(得分:9)

  

当然,这不是一个很好的例子,因为他们不能完成[0, 1, 2, 3, 4].sum()

JavaScript中没有标准Array#sum。这就是在那里使用:实现它:

Object.defineProperty(Array.prototype, "sum", {
    value: function() {
        return this.reduce(function(sum, item) { return sum + item; }, 0);
    }
});

(您可以在此特定示例中关闭, 0部分;如果您在没有种子值的情况下调用reduce,则首次调用回调会使用第一个条目作为第一个条目参数和第二个条目作为secodn。)

或任何其他类型的累积操作,例如产品,可能使用对象属性:

var foos = [
    {foo: 1},
    {foo: 2},
    {foo: 3}
];
var product = foos.reduce(function(p, obj) {
    return p * obj.foo;
}, 0);

或许是一项追加操作:

var list = [
    {name: "John"},
    {name: "Carla"},
    {name: "Mohammed"}
];
var names = list.reduce(function(acc, obj, index) {
    if (index === list.length - 1) {
        return acc + ", and " + obj.name;
    }
    return acc + ", " + obj.name;
});

几乎任何涉及累积值的操作都是我倾向于reduce的操作。

另一种用法(有些人会说 abusage )我经常看到的是当你想对数组中的每个项目执行某些操作时,需要将它添加到新的数组或对象,例如创建交叉 - 对象属性的数组索引:

var list = [
    {id: 1, name: "John"},
    {id: 2, name: "Carla"},
    {id: 3, name: "Mohammed"}
];
var index = list.reduce(function(o, item) {
    o[item.id] = item;
    return o;
}, {});

我说的原因"有些人会说 abusage "以上是上面的累加器(o)实际上并没有改变;它的状态发生了变化(我们为它添加了属性),但它的并没有,所以从那个意义上来说reduce并不存在用于它的预期目的:建立一个改变的价值。但我也经常看到这种用法,可能是因为它让我们在单个表达式中创建index而不是两个。

答案 1 :(得分:1)

我只是在codewars.com上使用.reduce()方法进行算法挑战。这是挑战:

  

皮特喜欢烤一些蛋糕。他有一些食谱和配料。   不幸的是,他在数学上并不擅长。你能帮他找出来吗,   考虑到他的食谱,他可以烘烤多少个蛋糕?

     

写一个函数cakes(),它取食谱(对象)和   可用成分(也是对象)并返回最大数量   蛋糕皮特可以烤(整数)。为简单起见,没有单位   对于这些量(例如1磅面粉或200克糖,只需1或   200)。物品中不存在的成分可以   被视为0。

     

示例:

// must return 2
cakes({flour: 500, sugar: 200, eggs: 1}, {flour: 1200, sugar: 1200, eggs: 5, milk: 200}); 
// must return 0
cakes({apples: 3, flour: 300, sugar: 150, milk: 100, oil: 100}, {sugar: 500, flour: 2000, milk: 2000});

这是解决方案:

function cakes(recipe, available) {
  return Object.keys(recipe).reduce(function(val, ingredient) {
    return Math.min(Math.floor(available[ingredient] / recipe[ingredient] || 0), val)
  }, Infinity)  
}

答案 2 :(得分:0)

其实我见过另一个例子; [https://forum.freecodecamp.com/t/freecodecamp-algorithm-challenge-guide-return-largest-numbers-in-arrays/16042] 他们使用了这个解决方案;

 function largestOfFour(arr) {
     return arr.map(function(group){
return group.reduce(function(prev, current) {
  return (current > prev) ? current : prev;
});
    });
}

这个问题;返回一个数组,该数组由每个提供的子数组中的最大数字组成。为简单起见,提供的数组将包含4个子数组。