4

I have 2 array:

    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]];

Want to get 1 merged array with the sum of corresponding keys;

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

Both arrays have unique keys, but the corresponding keys needs to be summed.

I tried loops, concat, etc but can't get the result i need.

anybody done this before?

1
  • 1
    Perhaps you could show us the attempt that you think was closest to working as desired. Commented Jun 14, 2013 at 18:43

5 Answers 5

6

You can use .reduce() to pass along an object that tracks the found sets, and does the addition.

DEMO: 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

If you need the result to be sorted, then add this to the end:

.sort(function(a,b) {
    return a[0] - b[0];
})
Sign up to request clarification or add additional context in comments.

Comments

4

This is one way to do it:

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.

Comments

0

a short routine can be coded using [].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]]

i like how it's just 3 line of code, doesn't need any internal function calls like push() or sort() or even an if() statement.

3 Comments

Your code doesn't seem to work in this situation, can you please check with it jsfiddle.net/wd2xov29/1/
@Sachin: GIGO, the arrays in the fiddle don't contain what you probably think: jsfiddle.net/wd2xov29/2
yeah that I know, but it also doesn't work if I put any two or more digit value at first index. Have a look jsfiddle.net/wd2xov29/3
0

Try this:

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));

So, the result may have holes. Just like 0th index. Use the below function if you want to ensure there are no holes.

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;

}

So, you can do:

var holesRemoved = compact(res);

And finally if you don't want the 0th elem of res. Do res.shift();

Disclaimer: I am not good with giving reasonable names.

Comments

0

The simple solution is like this.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.