JavaScript合并两个数组并将相同键值相加

4

我有两个数组:

    var array1 = [[5,10],[6,10],[7,10],[8,10],[9,10]];
    var array2 = [[1,10],[2,10],[3,10],[4,10],[5,40],[6,40]];

希望得到一个合并的数组,其中包括对应键的总和;

    var array1 = [[1,10],[2,10],[3,10],[4,10],[5,50],[6,50],[7,10],[8,10],[9,10]];

两个数组都有唯一的键,但是相应的键需要求和。

我尝试使用循环、连接等方法,但无法得到所需结果。

有没有人在此之前做过这个?


1
也许您可以展示一下您认为最接近预期工作的尝试。 - Lee Meador
5个回答

6
你可以使用 .reduce() 方法来传递一个跟踪已找到的集合并执行加法的对象。 演示: http://jsfiddle.net/aUXLV/
var array1 = [[5,10],[6,10],[7,10],[8,10],[9,10]];
var array2 = [[1,10],[2,10],[3,10],[4,10],[5,40],[6,40]];

var result =
    array1.concat(array2)
          .reduce(function(ob, ar) {
              if (!(ar[0] in ob.nums)) {
                  ob.nums[ar[0]] = ar
                  ob.result.push(ar)
              } else
                  ob.nums[ar[0]][1] += ar[1]

              return ob
          }, {nums:{}, result:[]}).result

如果您需要对结果进行排序,请在末尾添加以下内容:
.sort(function(a,b) {
    return a[0] - b[0];
})

4
这是一种做法:

这是一种做法:

var sums = {}; // will keep a map of number => sum

// for each input array (insert as many as you like)
[array1, array2].forEach(function(array) {
    //for each pair in that array
    array.forEach(function(pair) {
        // increase the appropriate sum
        sums[pair[0]] = pair[1] + (sums[pair[0]] || 0);
    });
});

// now transform the object sums back into an array of pairs
var results = [];
for(var key in sums) {
    results.push([key, sums[key]]);
}

See it in action.


0

简单的解决方案就是这样。

function sumArrays(...arrays) {
  const n = arrays.reduce((max, xs) => Math.max(max, xs.length), 0);
  const result = Array.from({ length: n });
  return result.map((_, i) => arrays.map(xs => xs[i] || 0).reduce((sum, x) => sum + x, 0));
}

console.log(...sumArrays([0, 1, 2], [1, 2, 3, 4], [1, 2])); // 2 5 5 4

0

试试这个:

var array1 = [[5,10],[6,10],[7,10],[8,10],[9,10]];
var array2 = [[1,10],[2,10],[3,10],[4,10],[5,40],[6,40]];
var res = [];

someReasonableName(array1, res);
someReasonableName(array2, res);

function someReasonableName(arr, res) {
  var arrLen = arr.length
  , i = 0
  ;

  for(i; i < arrLen; i++) {
    var ar = arr[i]
    , index = ar[0]
    , value = ar[1]

    ;

    if(!res[index]) {
        res[index] = [index, 0];
    }
    res[index][1] += value;
  }
}

console.log(JSON.stringify(res, null, 2));

因此,结果可能会有空洞。就像0索引一样。如果您想确保没有空洞,请使用以下函数。

function compact(arr) {
  var i = 0
  , arrLen = arr.length
  , res = []
  ;
  for(i; i < arrLen; i++) {
    var v = arr[i]
    ;
    if(v) {
      res[res.length] = v;
    }
  }
  return res;

}

所以,你可以做:

var holesRemoved = compact(res);

最后,如果你不想要res的第0个元素。可以使用 res.shift();

免责声明:我不善于给出合理的名称。


0
可以使用[].map()编写一个简短的程序。
var array1 = [[5,10],[6,10],[7,10],[8,10],[9,10]];
var array2 = [[1,10],[2,10],[3,10],[4,10],[5,40],[6,40]];

array1=array2.concat(array1).map(function(a){
  var v=this[a[0]]=this[a[0]]||[a[0]];
  v[1]=(v[1]||0)+a[1];
 return this;
},[])[0].slice(1);

alert(JSON.stringify(array1)); 
//shows: [[1,10],[2,10],[3,10],[4,10],[5,50],[6,50],[7,10],[8,10],[9,10]]

我喜欢它只有三行代码,不需要任何内部函数调用,如push()或sort()甚至if()语句。


你的代码在这种情况下似乎无法工作,你能否请检查一下:http://jsfiddle.net/wd2xov29/1// - Sachin
@Sachin:GIGO,fiddle中的数组不包含您可能认为的内容:http://jsfiddle.net/wd2xov29/2/ - dandavis
是的,我知道,但如果我在第一个索引处放置任何两个或更多位数值,它也不起作用。请看http://jsfiddle.net/wd2xov29/3/ - Sachin

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