Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does my reduce accumulator reset?

How do I retain the accumulative value of my reduce function? Each iteration resets the object value.

const a = [1, 2, 3, 4, 5];

const b = {
  1: {
    name: 'Dan',
    age: 25
  },
  2: {
    name: 'Peter',
    age: 28
  },
  3: {
    name: 'Mark',
    age: 38
  },
  4: {
    name: 'Larry',
    age: 32
  },
  5: {
    name: 'Simon',
    age: 25
  },
}

const f = a.reduce((acc, val) => {
  console.log({
    acc
  })
  return {
    [val]: {
      age: b[val].age
    }
  }
}, {})

console.log(f); // 5: {age: 25}

My desired outcome would be:

{
  1: { age: 25 },
  2: { age: 28 },
  3: { age: 38 },
  4: { age: 32 },
  5: { age: 25 },
}

(This example is a demo)

like image 960
Dan Avatar asked May 08 '18 10:05

Dan


2 Answers

Add the previous accumulator to the returned value using object spread (like this example) or Object.assign():

const a = [1, 2, 3, 4, 5];

const b = {"1":{"name":"Dan","age":25},"2":{"name":"Peter","age":28},"3":{"name":"Mark","age":38},"4":{"name":"Larry","age":32},"5":{"name":"Simon","age":25}};

const f = a.reduce((acc, val) => ({
  ...acc, // previous accumulator
  [val]: {
    age: b[val].age
  }
}), {})

console.log(f); // 5: {age: 25}
like image 50
Ori Drori Avatar answered Oct 18 '22 03:10

Ori Drori


As per MDN

The reduce() method applies a function against an accumulator and each element in the array (from left to right) to reduce it to a single value.

On each iteration you return new object inside of reduce() function and you are not storing previous value of that accumulator. So you need to be merge or assign previous value with new value.

One way you can use Object.assign() method to get the required result.

DEMO

const a = [1, 2, 3, 4, 5];

const b = {1: {name: 'Dan',age: 25},2: {name: 'Peter',age: 28},3: {name: 'Mark',age: 38},4: {name: 'Larry',age: 32},5: {name: 'Simon',age: 25}}

let result = a.reduce((acc, val) => Object.assign(acc,{[val]: {age:b[val].age}}), {});

console.log(result);
.as-console-wrapper {max-height: 100% !important;top: 0;}

second way you can do like this obje[val]=newValue and return accumulator.

DEMO

const a = [1, 2, 3, 4, 5];

const b = {1: {name: 'Dan',age: 25},2: {name: 'Peter',age: 28},3: {name: 'Mark',age: 38},4: {name: 'Larry',age: 32},5: {name: 'Simon',age: 25}}

let result = a.reduce((acc, val) =>{
acc[val]= {age:b[val].age};
return acc;
}, {});

console.log(result);
.as-console-wrapper {max-height: 100% !important;top: 0;}

Another way you can combine using the spread syntax

DEMO

const a = [1, 2, 3, 4, 5];

const b = {1: {name: 'Dan',age: 25},2: {name: 'Peter',age: 28},3: {name: 'Mark',age: 38},4: {name: 'Larry',age: 32},5: {name: 'Simon',age: 25}}

let result = a.reduce((acc, val) => {
return {...acc,...{[val]:{age:b[val].age}}}
}, {});

console.log(result);
.as-console-wrapper {max-height: 100% !important;top: 0;}
like image 41
Narendra Jadhav Avatar answered Oct 18 '22 03:10

Narendra Jadhav