1

What is the best way to reduce this array of objects to get the desired result?

const arr = [
  {
          "id": "561",
          "count": "1",
          "month": 7
      },
      {
          "id": "561",
          "count": "1",
          "month": 7
      },
      {
          "id": "561",
          "count": "-1",
          "month": 8
      },
      {
          "id": "561",
          "count": "1",
          "month": 9
      },
      {
          "id": "561",
          "count": "-1",
          "month": 9
      }
  ]

As you can see the id matches and some of the months match. What I would like to achieve is something along the lines of:

[
  {
    "id": "561",
    "count": 2
    "month": 7
  },
  {
    "id": "561",
    "count": -1,
    "month": 8
  },
  {
    "id": "561",
    "count": 0,
    "month": 9
  }
]

I'm basically trying to get the total count by month per id.

2 Answers 2

2

You can use Array.prototype.reduce to group and evaluate your array based on id and month

const arr = [
  {
          "id": "561",
          "count": "1",
          "month": 7
      },
      {
          "id": "561",
          "count": "1",
          "month": 7
      },
      {
          "id": "561",
          "count": "-1",
          "month": 8
      },
      {
          "id": "561",
          "count": "1",
          "month": 9
      },
      {
          "id": "561",
          "count": "-1",
          "month": 9
      }
  ];
  
const res = Object.values(arr.reduce((acc, item) => {
   if (acc[`${item.id}-${item.month}`]) {
      acc[`${item.id}-${item.month}`] = {
        ...acc[`${item.id}-${item.month}`],
        count: `${parseInt(acc[`${item.id}-${item.month}`].count) + parseInt(item.count)}`
      }
   } else {
    acc[`${item.id}-${item.month}`] = item;
   }
   return acc;
}, {}));
console.log(res);

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

2 Comments

You are concatenating the count value not adding ...
@RobinMackenzie I updated that part in my solution, I didn't see that count was a string in OP question
1

Here's an example using Array.prototype.reduce to create a new array and Array.prototype.find to check if the current value is already present in the new array

const arr = [
  {
          "id": "561",
          "count": "1",
          "month": 7
      },
      {
          "id": "561",
          "count": "1",
          "month": 7
      },
      {
          "id": "561",
          "count": "-1",
          "month": 8
      },
      {
          "id": "561",
          "count": "1",
          "month": 9
      },
      {
          "id": "561",
          "count": "-1",
          "month": 9
      }
  ]

const result = arr.reduce((acc, value) => {
  const index = acc.findIndex(({id, month}) => id === value.id && month === value.month);
  if( index > -1 ) {
    acc[index]['count'] += Number(value.count);
  }
  else {
    acc.push({...value, count: Number(value.count)});
  }
  return acc;
}, [])

console.log(result)

2 Comments

id of 561 and month 7 should have count of 2...
@RobinMackenzie ah, I've missed that part in the question. thanks

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.