I have an array like this:
const inputArray = [
{
userId: 1,
sum: 30,
},
{
userId: 1,
sum: 20,
},
{
userId: 2,
sum: 50,
},
{
userId: 2,
sum: 80,
},
];
Then I wrote a function that sums the values by key and got the following result:
const output = [
{
userId: 1,
sum: 50,
},
50,
{
userId: 2,
sum: 130,
},
130,
];
How can this error be corrected? Function code below:
const output = inputArray.reduce((accumulator, currentItem) => {
const index = accumulator.findIndex((item) => item.userId === currentItem.userId);
if (index < 0) {
return [...accumulator, currentItem];
} else {
return [...accumulator, (accumulator[index].sum += currentItem.sum)];
}
}, []);
-
What is the expected result?VLAZ– VLAZ2021年12月03日 11:10:40 +00:00Commented Dec 3, 2021 at 11:10
-
@VLAZ I think he just want the same array with the sum property incrementederoironico– eroironico2021年12月03日 11:11:11 +00:00Commented Dec 3, 2021 at 11:11
-
@Nick and I think it would be good to include all relevant information in the question itself.VLAZ– VLAZ2021年12月03日 11:11:47 +00:00Commented Dec 3, 2021 at 11:11
-
Write that so...eroironico– eroironico2021年12月03日 11:12:51 +00:00Commented Dec 3, 2021 at 11:12
3 Answers 3
I would suggest, instead of finding index as it can be costly iterating array again and again, you can simply make an object with userId as key and sum as value.
After that, u can do Object.entries(inputObj) to make and array of object out of this.
var inputArray = [{ userId: 1,sum: 30},{userId: 1,sum: 20},{userId: 2,sum: 50},{userId: 2,sum: 80}];
var outputObj = inputArray.reduce((finalObj, curObj) => {
if (!finalObj[curObj.userId]) finalObj[curObj.userId] = curObj.sum //<--- adding new user if do not exist in the object
else finalObj[curObj.userId] += curObj.sum; // <---- if already present, the add the sum
return finalObj;
}, {})
var output = Object.entries(outputObj).map((obj) => ({
userId: obj[0], //<--- key of object as userId
sum: obj[1] //<--- value of object as sum
}));
console.log(output)
Comments
Try
const inputArray = [
{
userId: 1,
sum: 30,
},
{
userId: 1,
sum: 20,
},
{
userId: 2,
sum: 50,
},
{
userId: 2,
sum: 80,
},
];
const output = inputArray.reduce((accumulator, currentItem) => {
const matchedItem = accumulator.find((item) => item.userId === currentItem.userId);
if (!matchedItem) {
return [...accumulator, currentItem];
} else {
matchedItem.sum += currentItem.sum
return accumulator
}
}, []);
console.log(output)
you were appending a new item to accumulator even when the item already existed, you just needed to mutate it. Also, since you dealing with an array of objects, you can use find as it will return a reference to the matched object itself, letting you update the object directly, rather than having to use findIndex then use the index to find it in the array again
2 Comments
You can try this:
const inputArray = [
{
userId: 1,
sum: 30,
},
{
userId: 1,
sum: 20,
},
{
userId: 2,
sum: 50,
},
{
userId: 2,
sum: 80,
},
];
const res = Array.from(inputArray.reduce((m, {userId, sum}) => m.set(userId, (m.get(userId) || 0) + sum), new Map), ([userId, sum]) => ({userId, sum}));