使用underscore js的reduce方法

4

underscorejs的reduce如何工作?

使用 _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0); 很简单(结果为6)。

但是其他可选参数是如何工作的呢?在文档中写到:

Memo 是 reduction 的初始状态,每个成功的迭代应该由 iterator 返回。iterator 接收四个参数:memo、value、iteration 的 index(或 key),最后是整个 list 的引用。

但我不理解。我尝试将reduce用于以下问题,但我无法理解:

var input = [{"score": 2, "name": "Jon", "venue": "A"}, {"score": 3, "name": "Jeff", "venue":"A"}, {"score": 4, "name": "Jon", "venue":"B"}, {"score": 4, "name": "Jeff", "venue":"B"}];

var output = [{"score": 6, "name":"Jon", "venue": ["A", "B"]}, {"score": 7, "name":"Jeff", "venue": ["A", "B"]}];

我该如何使用_reduce来输出输入?了解在reduce内部运作的方式会非常有帮助。

请展示你尝试过的内容,这样我们可以看到你具体哪些地方存在误解。memo 只是初始值,在后续迭代中成为上一个返回值。其余参数与 .map().forEach() 等方法一样。 - user2437417
2个回答

10

Reduce需要一个值列表,并将其减少为单个值。你尝试的不只是reduce。你想先按名称分组,然后减少每个组。一个可能的实现方式是这样的,首先进行分组,然后将每个组映射到累加分数和追加场馆的reduce操作。

var input = [
    {"score": 2, "name": "Jon", "venue": "A"}, 
    {"score": 3, "name": "Jeff", "venue":"A"}, 
    {"score": 4, "name": "Jon", "venue":"B"}, 
    {"score": 4, "name": "Jeff", "venue":"B"}];

var output = _.map(_.groupBy(input, "name"), function(group, name) {
    return _.reduce(group, function(memo, elem) { 
            memo.score += elem.score;
            memo.venue.push(elem.venue);
            return memo;
        },
        { name: name, score: 0, venue: [] });
});

2

不要使用reduce,尝试以简单明了的方式使用each

_.each可以接受第三个参数作为上下文。例如:

var input = ["Alice", "Bob", "Charlie"];
var context = {};

_.each(input, function(o,i) { this[i] = o; }, context);

console.log(context) //=> {1: "Alice", 2: "Bob", 3: "Charlie"}

Ruby有一个称为each_with_object的新方法,类似于reduce的确切模式,其中memo不一定是返回的值(实际上,我的函数没有返回任何东西!);但underscore简化了其API设计,只需将函数的上下文作为第三个参数传递即可。
您可以使用reduce,但每次都需要返回memo,这使得它稍微不太优雅。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接