Javascript:通过Key总结多个数组的最有效方法

时间:2015-10-22 18:15:06

标签: javascript arrays loops for-loop

我有一个从Web服务返回的JSON对象,它是一个对象数组。我需要添加"数据"数组一起形成一个求和数组。 JSON响应如下所示:

[  
  {  
    "data":[  
       0,3,8,2,5
    ],
    "someKey":"someValue"
  },
  {  
    "data":[  
       3,13,1,0,5
    ],
    "someKey":"someOtherValue"
  }
]

数组中可能有N个对象。上述示例的所需输出为:

[3, 16, 9, 2, 10]

我打算创建一个空数组变量(var arr),然后循环遍历这些对象,并为每个对象循环遍历"数据"键和每个键增加arr中相应的键值。

使用某种合并功能有更有效的方法吗?

3 个答案:

答案 0 :(得分:2)

这个怎么样,我相信它应该适用于所有情况。



var data = [{
  "data": [
    0, 3, 8, 2, 5
  ],
  "someKey": "someValue"
}, {
  "data": [
    3, 13, 1, 0, 5
  ],
  "someKey": "someOtherValue"
}];

var datas = data.reduce(function(a, b) {
  b.data.forEach(function(x, i) {
    a[i] = a[i] || 0;
    a[i] += x;
  });
  return a;
}, []);

console.log(datas);




答案 1 :(得分:1)

如果每个对象的长度都相同data,您可以尝试使用:

var input; // Your input data
var output = [];
for (var i = 0; i < input[0].data.length; i++) {
  output[i] = input.reduce(function(prev, item) {
    return +(item.data[i]) + prev;
  }, 0);
}

console.log(output);
// [3, 16, 9, 2, 10]

如果每个对象的大小不同data

var input; // Your input data
var i = 0, output = [];
while (true) {
  var outOfIndex = true;

  var sum = input.reduce(function(prev, item) {
    if (item.data[i] !== undefined) {
      outOfIndex = false;
    }
    return +(item.data[i]) + prev;
  }, 0);

  if (outOfIndex) {
    break;
  }
  output[i++] = sum;
}

console.log(output);
// [3, 16, 9, 2, 10]

答案 2 :(得分:0)

稍微不那么迫切的解决方案:

//zip takes two arrays and combines them per the fn argument
function zip(left, right, fn) {
   var shorter = (right.length > left.length) ? left : right;
   return shorter.map(function(value, i) {
       return fn(left[i], right[i]);
   });
}

//assuming arr is your array of objects. Because were using
//zip, map, and reduce, it doesn't matter if the length of the
//data array changes
var sums = arr
    .map(function(obj) { return obj.data; })
    .reduce(function(accum, array) {

        //here we want to combine the running totals w/the current data
        return zip(accum, array, function(l, r) { return l + r; });
    });