2013-08-01 76 views
4

underscorejs reduce如何工作?使用下划线js 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输入输出,这将非常有帮助的工作机制减少

+0

请显示您尝试过的内容,以便我们明确了解您误解的内容。 “备忘录”首先是初始值,然后是之后的迭代的返回值。其余的参数是你对'.map()'或'.forEach()'方法的典型参数。 –

回答

9

减少花费?一个值列表,并将其减少到一个单一的值。你所尝试的不是ju st减少。您正在尝试先(按名称)分组,然后再减少每个组。一个可能的实现将是这样的,你首先进行分组,然后将每个分组映射到一个减少操作,积累分数并附加场地。

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: [] }); 
}); 
1

相反的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类似于减少,准确的模式,其中备忘录并不一定是价值回归(其实,我的功能不返回任何东西!);但下划线简化了它的API设计,只是将该函数的上下文作为第三个参数。

你可以使用减少,但你需要每次都返回备忘录,使它不那么优雅恕我直言。