Sara Ree
Sara Ree

Reputation: 3543

How to sum up a 2D array elements together?

Here is a simple code sample of what I'm after:

var length = 5;
var arrays = [];


// our arrays

         slice1  
         ↓  slice2
            ↓  ↓ slice3
var a = [1, 1, 1, 1, 1];
var b =    [2, 2, 2, 2];
var c =       [3, 3, 3];
var d =          [4, 4];
var e =             [5];
                     ↑ slice5
// put all above arrays into one array
arrays = arrays.concat([a]);
arrays = arrays.concat([b]);
arrays = arrays.concat([c]);
arrays = arrays.concat([d]);
arrays = arrays.concat([e]);
console.log(arrays)

for (let i = 0; i < length; i++){
 /*         
I want a code here which does this:
var slice = [];
slice[0] = arrays[0][0] => 1
slice[1] = arrays[0][1] + arrays[1][0] => 1 + 2
slice[2] = arrays[0][2] + arrays[1][1] + arrays[2][0] => 1 + 2 + 3
...
*/
}

Actually, I want to assign slice variables based on a 2D array elements. But how?

Note: I can log the arrays but the problem is to calculate each slice in the for loop because I may have different a, b, c, d or different length.

Upvotes: 3

Views: 110

Answers (3)

Nina Scholz
Nina Scholz

Reputation: 386560

You could reduce the array and take an offset for the index by iterating from the end for the inner array. This works for an arbitrary length of the arrays.

Some different values to proof the calculation.

[[1, 10, 100, 1000, 10000],
    [20, 200, 2000, 20000],
        [300, 3000, 30000],
             [4000, 40000],
                   [50000]]

[ 1, 30, 600,10000, 150000]

var array = [[1, 10, 100, 1000, 10000], [20, 200, 2000, 20000], [300, 3000, 30000], [4000, 40000], [50000]],
    result = array.reduce((r, a) => a.reduceRight((q, v, i, { length }) => {
        if (q.length < length - i) q.unshift(v);
        else q[q.length - length + i]+= v;
        return q;
    }, r), []);
    
  console.log(result);

Upvotes: 2

Mark
Mark

Reputation: 92440

Here's a way to do this for any arrangement of arrays. It should work even if the arrays are in different orders to different lengths. The trick is assigning zero if the array isn't initialized at the particular index.

var a = [1, 1, 1, 1, 1];
var b =    [2, 2, 2, 2];
var c =       [3, 3, 3];
var d =          [4, 4];
var e =             [5];
// put all above arrays into one array
let arrays = [a, b, c, d, e]

let sums = arrays.reduce((sums, arr) => {
    arr.reverse().forEach((n, i) => sums[i] = (sums[i] || 0) + n)
    return sums
}, []).reverse()

console.log(sums)

Other arrangements/lengths will work as expected:

var a =   [10, 2, 2, 2];
var b =[1, 20, 1, 1, 1];
var c =       [3, 3, 3];
var d =          [4, 4];
var e =       [5, 5, 5];

let arrays = [a, b, c, d, e] 

let sums = arrays.reduce((sums, arr) => {
    arr.reverse().forEach((n, i) => sums[i] = (sums[i] || 0) + n)
    return sums
}, []).reverse()

console.log(sums)

Upvotes: 1

GalAbra
GalAbra

Reputation: 5148

In my opinion the best approach to an algorithm as you've described is to find an inductive rule, just like you aimed to!

var length = 5;
var arrays = [];
var slices = new Array(length).fill(0);

// I thought this was a more elegant way of initializing
for (let i = length; i > 0; i--){
  arrays[length-i] = new Array(i).fill(length+1-i);
}

for (let i = 0; i < length; i++) {
  for (let j = 0; j <= i; j++) {
    slices[i] += arrays[j][i - j];
  }
}
console.log(slices);

Upvotes: 2

Related Questions