1

i have an array with objects inside which contain values "x" and "y", i'm trying to sum only "y" in a way that it acumulates it's value.

These are the objects i currently have

obj[0]: {x: "2020-09-30", y: 593}
obj[1]: {x: "2020-09-29", y: 100}
obj[2]: {x: "2020-09-25", y: 331}
obj[3]: {x: "2020-09-24", y: 901}
obj[4]: {x: "2020-09-21", y: 50}

These is the result im looking for

obj[0]: {x: "2020-09-30", y: 593}
obj[1]: {x: "2020-09-29", y: 693}
obj[2]: {x: "2020-09-25", y: 1024}
obj[3]: {x: "2020-09-24", y: 1925}
obj[4]: {x: "2020-09-21", y: 1975}

this is a snippet i came up with but doesn't work, does anyone have an idea how it could work?

for(var i=1; i<=obj.length; i++){
            var j=i-1
            obj[i.y] = obj[i.y] + obj[j.y]
        }
  • You are mutating the array you are running on. That is a bad practice. Try using array.map() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map – Ori Price Oct 06 '20 at 17:27
  • So you want a running total in reverse time? That's a bit odd... – Heretic Monkey Oct 06 '20 at 17:40

7 Answers7

2

Array.forEach() as has more than one argument!

const obj=
  [ { x: "2020-09-30", y: 593 }
  , { x: "2020-09-29", y: 100 }
  , { x: "2020-09-25", y: 331 }
  , { x: "2020-09-24", y: 901 }
  , { x: "2020-09-21", y:  50 }
  ]

obj.forEach((e,i,a)=>e.y += i? a[i-1].y : 0)

console.log( obj )
.as-console-wrapper { max-height: 100% !important; top: 0; }
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
0

You can do it using Array.reduce.

const input = [
  {x: "2020-09-30", y: 593},
  {x: "2020-09-29", y: 100},
  {x: "2020-09-25", y: 331},
  {x: "2020-09-24", y: 901},
  {x: "2020-09-21", y: 50}
];

const result = input.reduce((acc, curV, curI) => {
  if (curI > 0) {
    acc.push({
      x: curV.x,
      y: curV.y + acc[curI - 1].y
    });
  } else {
    acc.push(curV);
  }
  return acc;
}, []);

console.log(result);
Derek Wang
  • 10,098
  • 4
  • 18
  • 39
0

You could take a closure over the sum and increment this value at each iteration.

const
    array = [{ x: "2020-09-30", y: 593 }, { x: "2020-09-29", y: 100 }, { x: "2020-09-25", y: 331 }, { x: "2020-09-24", y: 901 }, { x: "2020-09-21", y: 50 }],
    result = array.map(
        (sum => o => ({ ...o, y: sum += o.y }))
        (0)
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

You need to use reduce method of array, like this snippet.

const obj = [{
  x: "2020-09-30",
  y: 593
}, {
  x: "2020-09-29",
  y: 100
}, {
  x: "2020-09-25",
  y: 331
}, {
  x: "2020-09-24",
  y: 901
}, {
  x: "2020-09-21",
  y: 50
}]


const newarr = obj.reduce((prev, data, key) => {
  return [
    ...prev,
    {
      ...data,
      y: (prev[key - 1]?.y ?? 0) + data.y
    }
  ]
}, []);

console.log(newarr);
Shridhar Sharma
  • 2,337
  • 1
  • 9
  • 13
0

You are mutating the array you are running on. That is a bad practice. Try using array.map()

obj.map((currentValue, index) => ({ 
   ...currentValue,
   y: ( index-1 > 0 )? currentValue.y + obj(index-1).y : obj.y
 }))
Ori Price
  • 3,593
  • 2
  • 22
  • 37
0

As @Ori Price commented, you should not mutate variables, but return new ones. This is because it can have unwanted side effects.

This is one of many several solutions.

const obj = [{x: "2020-09-30", y: 593}, {x: "2020-09-29", y: 100}, {x: "2020-09-25", y: 331}, {x: "2020-09-24", y: 901}, {x: "2020-09-21", y: 50}]

const accumulateY = (obj) => {
  let accumulator = 0;
  return obj.map((element) => {
    accumulator += element.y
    return {...element, y: accumulator};
  })
}

const newObj = accumulateY(obj);
console.log(newObj);
Paalar
  • 175
  • 1
  • 8
0

if you want to mutate the array you have you can also use a simple for-of and sum it with a variable from outside.

const input = [
  {x: "2020-09-30", y: 593},
  {x: "2020-09-29", y: 100},
  {x: "2020-09-25", y: 331},
  {x: "2020-09-24", y: 901},
  {x: "2020-09-21", y: 50}
];

let sum = 0;

for(let item of input) {
  item.y = sum += item.y;
}


console.log(input);
Saar Davidson
  • 1,312
  • 1
  • 7
  • 16