Burak Özdemir
Burak Özdemir

Reputation: 560

Creating a 2d array that consisted of another 2d array's acumulation

I have an array which is like that: [[0, 50], [1, 40], [2, 30], [3, 20], [5, 10]]

And I want to accumulative the second values: [[0, 50], [1, 90], [2, 120], [3, 140], [5, 150]]

I tried the code part below which works for one dimensional arrays, but it doesn't work for 2d arrays. Is it possible to accumulate it by using reduce function? Or is there different way to do it?

var array1 = [[0, 50], [1, 40], [2, 30], [3, 20], [5, 10]];
var newArray1 = [];

array1.reduce(
    function (previousValue, currentValue, currentIndex) {
        return newArray1[currentIndex] = [currentIndex, (previousValue[1] + currentValue[1])];
    }, 0
);

Upvotes: 1

Views: 60

Answers (3)

Redu
Redu

Reputation: 26201

Just for fun lets invent a new array functor, Array.prototype.extend() This works like opposite to the reduce. It takes an array and extends it starting from the last item by utilizing a provided callback. When the callback returns undefined it sops extending. Let see how we can have fun with it in this particular case;

Array.prototype.extend = function(cb){
  var len = this.length + 1,
      res = cb(this[len-1], len-1, this);
  return res ? this.extend(cb) : this;
};

var arr = [[0, 50], [1, 40], [2, 30], [3, 20], [5, 10]],
     cb = function(e,i,a){
     	    return i === 0 ? a.push(arr[i])
     	                   : i < arr.length ? a.push([arr[i][0], arr[i][1] + a[i-1][1]])
     	                                    : void 0;
          };
 result = [].extend(cb);
 console.log(result);

Upvotes: 0

Pranav C Balan
Pranav C Balan

Reputation: 115282

Use Array#reduce method

var array1 = [
  [0, 50],
  [1, 40],
  [2, 30],
  [3, 20],
  [5, 10]
];

// initialize as the array of first element in original array
var newArray1 = [array1[0].slice()];

array1
  // get remaining array element except first
  .slice(1)
  // iterate over the array value to generate result array
  .reduce(function(arr, v, i) {
    // copy the array element if you don't want to refer the old
    v = v.slice();
    // add previous array value
    v[1] += arr[i][1];
    // push updated array to result array
    arr.push(v);
    // retur the updated array
    return arr;
    // set initial value as array which contains first element(array) copy
  },newArray1);


console.log(newArray1)


UPDATE 1: Another method with less code

var array1 = [
  [0, 50],
  [1, 40],
  [2, 30],
  [3, 20],
  [5, 10]
];

var newArray1 = [array1[0].slice()];

array1.slice(1).reduce(function(arr, v, i) {
  arr.push([v[0], v[1] + arr[i][1]]);
  return arr;
}, newArray1);


console.log(newArray1)


UPDATE 2 : Much more reduced version without using Array#slice method.

var array1 = [
  [0, 50],
  [1, 40],
  [2, 30],
  [3, 20],
  [5, 10]
];

var newArray1 = array1.reduce(function(arr, v, i) {
  // push value to array add value only if `arr` contains any element
  arr.push([v[0], v[1] + (arr.length && arr[i - 1][1])]);
  return arr;
  // set initial value as an empty array
}, []);


console.log(newArray1)

Upvotes: 1

Nenad Vracar
Nenad Vracar

Reputation: 122155

You can use map() with optional thisArg parameter

var array1 = [[0, 50], [1, 40], [2, 30], [3, 20], [5, 10]];

var result = array1.map(function(e) {
  this.num = (this.num || 0) + e[1];
  return [e[0], this.num];
}, {});

console.log(result);

Upvotes: 3

Related Questions