4

underscorejs 是如何reduce工作的?

很容易得到 _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0);(结果是6)。

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

备忘录是归约的初始状态,它的每一步都应该由迭代器返回。迭代器被传递了四个参数:备忘录,然后是迭代的值和索引(或键),最后是对整个列表的引用。”

但我不明白。我试图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 内部的工作方式非常有帮助。

4

2 回答 2

10

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: [] });
});
于 2013-08-01T22:22:15.717 回答
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,但每次都需要返回备忘录,恕我直言,它有点不那么优雅。

于 2013-08-01T22:25:19.110 回答