Javascript - sum of 2d arrays

I have 2 2d arrays

var arr1 = [ [1, 'a'], [2, 'b'] ] var arr2 = [ [3, 'a'], [5, 'c'] ] 

I would like to sum these 2 arrays to get this result

 var output = [ [4, 'a'], [2, 'b'], [5, 'c'] ] 

I tried to write 2 .map functions, but along with the desired results, this will return a lot of duplicates:

 function sumArrays (arr1, arr2) { var output = []; arr2.map(function(i) { arr1.map(function(n) { if (i[1] === n[1]) { output.push([i[0] + n[0], i[1]]) } else { output.push(i) } }) }) return output; } 

Is there an easier way to do this, or should I now delete everything except the highest value for a specific row?

Thanks for the help.

+5
source share
4 answers

Please use Array#map when you do not need a new array returned by this method.

You can use the hash table for inventory, and also check and update arr2 with Array#forEach .

The sentence that arr1 uses to update

 var arr1 = [[1, 'a'], [2, 'b']], arr2 = [[3, 'a'], [5, 'c']], inventory = Object.create(null); arr1.forEach(function (a) { this[a[1]] = a; }, inventory); arr2.forEach(function (a) { if (!this[a[1]]) { this[a[1]] = [0, a[1]]; arr1.push(this[a[1]]); } this[a[1]][0] += a[0]; }, inventory); console.log(arr1); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

Sentence with a new array for result .

 var arr1 = [[1, 'a'], [2, 'b']], arr2 = [[3, 'a'], [5, 'c']], inventory = Object.create(null), result = arr1.map(function (a) { return this[a[1]] = [a[0], a[1]]; }, inventory); arr2.forEach(function (a) { if (!this[a[1]]) { this[a[1]] = [0, a[1]]; result.push(this[a[1]]); } this[a[1]][0] += a[0]; }, inventory); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 
+3
source

This question is essentially the same as this , where I suggested the same ES6 code using hashes (Set) and some version of the code that I will not repeat here

 function sumArrays(a, b) { return Array.from( b.reduce( (m, [v,k]) => m.set(k, (m.get(k) || 0) + v), new Map(a.map ( ([v,k]) => [k,v] )) ), // swap pairs ([k,v]) => [v,k]) // swap back afterwards; } var arr1 = [ [1, 'a'], [2, 'b'] ] var arr2 = [ [3, 'a'], [5, 'c'] ] var result = sumArrays(arr1, arr2); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 
0
source

You can also do this with forEach() and findIndex() .

 var arr1 = [ [1, 'a'], [2, 'b'] ] var arr2 = [ [3, 'a'], [5, 'c'] ] function sumArrays(arr1, arr2) { var r = arr1.slice(0); arr2.forEach(function(e) { var i = arr1.findIndex(function(a) { return e[1] == a[1]; }) i != -1 ? r[i][0] += e[0] : r.push(e) }) return r; } console.log(sumArrays(arr1, arr2)) 
0
source

Align both arrays so that you have one array with all tuples.

Then reduce this array of tuples so that all compatible tuples accumulate.

 arr1.concat(arr2).reduce(function r(accumulator, iterand) { // base case: no tuples in accumulator if (accumulator.length == 0) { // add current tuple to our empty accumulator. return [iterand]; } // first tuple in accumulator is compatible with the currently-inspected tuple if (accumulator[0][1] == iterand[1]) { // increment the count in the compatible tuple that already exists in the accumulator return [[accumulator[0][0]+iterand[0], accumulator[0][1]]].concat(accumulator.slice(1)); } // currently-inspected tuple is not compatible with first tuple in accumulator. leave first tuple in accumulator unchanged. run the inductive case upon the remaining tuples in the accumulator. return [accumulator[0]].concat(r(accumulator.slice(1), iterand)); }, []) 

This is a functional solution that will not mutate any existing input.

0
source

Source: https://habr.com/ru/post/1258631/


All Articles