0

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)];
  }
}, []);

4
  • What is the expected result? Commented Dec 3, 2021 at 11:10
  • @VLAZ I think he just want the same array with the sum property incremented Commented Dec 3, 2021 at 11:11
  • @Nick and I think it would be good to include all relevant information in the question itself. Commented Dec 3, 2021 at 11:11
  • Write that so... Commented Dec 3, 2021 at 11:12

3 Answers 3

1

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)

Sign up to request clarification or add additional context in comments.

Comments

0

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

Yes, it works, but this way mutates the original array
so whats the problem with mutating the array?
0

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}));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.