17

我在这里做了一个小 plnkr来展示我想要实现的目标。我有一个大数据集,我喜欢将单个类型相加得到总数。

我可以考虑迭代并将结果添加到对象哈希中,但想知道用下划线解决它的更优雅的方法。我正在使用 underscore.js,但从未尝试过 map reduce 或其他功能范式。请更新 plnkr 以了解如何执行此操作。

http://plnkr.co/edit/B5HGxhwvWsfvOR97z7TL?p=preview

var data = [ {'type': "A", 'val':2},
  {'type': "B", 'val':3},
  {'type': "A", 'val':1},
  {'type': "C", 'val':5} ];


 _.each(data, function (elm, index) {
   console.log(elm);  
 });

 /*
 Desired output

 out = [ {'type': "A", 'total':3},
  {'type': "B", 'total':3},
  {'type': "C", 'total':5} ];

 */
4

3 回答 3

32
var data = [ { type: "A", val: 2 },
             { type: "B", val: 3 },
             { type: "A", val: 1 },
             { type: "C", val: 5 } ];

var groups = _(data).groupBy('type');

var out = _(groups).map(function(g, key) {
  return { type: key, 
           val: _(g).reduce(function(m,x) { return m + x.val; }, 0) };
});

演示

于 2013-01-20T23:31:47.967 回答
12

与@GregL 的答案几乎相同,只是多了一点下划线:

summed_by_type = _(data).reduce(function(mem, d) {
  mem[d.type] = (mem[d.type] || 0) + d.val
  return mem
}, {})

pairs = _(summed_by_type).map(function(v,k) { return {type: k, total: v} })
于 2013-01-20T23:35:15.423 回答
5

以下将起作用,但我认为它与您的想法相似。优点是通过使用对象散列来存储总数,您可以在类型上建立索引,这意味着您不必每次尝试查找具有正确类型的对象时都遍历散列。然后在最后遍历它一次以构建最终的输出数组。

Plunkr 来

代码如下:

var data = [ {'type': "A", 'val':2},
  {'type': "B", 'val':3},
  {'type': "A", 'val':1},
  {'type': "C", 'val':5} ];

var totalPerType = {};
for (var i = 0, len = data.length; i < len; ++i) {
  totalPerType[data[i].type] = totalPerType[data[i].type] || 0;
  totalPerType[data[i].type] += data[i].val;
}
var out = _.map(totalPerType, function(sum, type) {
  return { 'type': type, 'total': sum };
});

 console.log('out = ', out);

编辑:我创建了一个新的 plunkr,它甚至可以在此处生成 100 万个项目数组(有 6 种可能的类型)速度。从控制台输出可以看出,至少在 Chrome Canary 中,它的运行时间约为 1/3 秒。

我还做了一个jsPerf 测试,测试使用中间散列的速度有多快,结果大约快了 50%。

于 2013-01-20T23:13:30.583 回答