Reputation: 817
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)
Upvotes: 5
Views: 1309
Reputation: 1107
Your reduce accumulator can also reset if you happen to have an if else statement in your reduce function, whereby you return an accumulator for the if statement but forget to handle the else statement and do not return an accumulator - in that case when the else statement is triggered no accumulator is returned and the accumulator becomes undefined.
For example this works:
let reducedArray = array.reduce((acc, curr) => {
if (
curr[
property_name
]
) {
return {
...acc,
...{
[curr.id]:
(acc[curr.id] ?? 0) +
curr[
property_name
]!
},
};
} else {
return acc;
}
}, {} as { [key: string]: number });
But this will not work:
let reducedArray = array.reduce((acc, curr) => {
if (
curr[
property_name
]
) {
return {
...acc,
...{
[curr.id]:
(acc[curr.id] ?? 0) +
curr[
property_name
]!
},
};
}
}, {} as { [key: string]: number });
Upvotes: 0
Reputation: 10262
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;}
Upvotes: 1
Reputation: 191976
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}
Upvotes: 6