Search code examples
javascriptarraysobjectreduce

Count an array of objects


const array = [
  { date: '2022-01-03', answer: 'yes' },
  { date: '2022-01-03', answer: 'no' },
  { date: '2022-01-03', answer: 'no' },
  { date: '2022-01-04', answer: 'yes' },
  { date: '2022-01-04', answer: 'yes' },
  { date: '2022-01-05', answer: 'yes' },
  { date: '2022-01-05', answer: 'yes' },
  { date: '2022-01-05', answer: 'yes' },
  { date: '2022-01-05', answer: 'no' },
]

And I'm expecting a result something like this:

{
    "2022-01-03" : [
        {
            "yes": 1,
            "no": 2
        }
    ],
    "2022-01-04" : [
        {
            "yes": 2,
            "no": 0
        }
    ],
    "2022-01-05" : [
        {
            "yes": 3,
            "no": 1
        }
    ]
}

I've been trying to do it this way but I can't find a way to make it work:

const array = [
  { date: '2022-01-03', answer: 'yes' },
  { date: '2022-01-03', answer: 'no' },
  { date: '2022-01-03', answer: 'no' },
  { date: '2022-01-04', answer: 'yes' },
  { date: '2022-01-04', answer: 'yes' },
  { date: '2022-01-05', answer: 'yes' },
  { date: '2022-01-05', answer: 'yes' },
  { date: '2022-01-05', answer: 'yes' },
  { date: '2022-01-05', answer: 'no' },
]

const result = array.reduce((prev, curr) => {
  prev[curr.date] = prev[curr.date] || [];
  prev[curr.date].push(curr.answer)
  return prev;
}, {});

console.log(result)


Solution

  • Your reduce is close; it's just a matter of making sure you create objects within each date key to count the yes/no answers.

    const array = [
      { date: '2022-01-03', answer: 'yes' },
      { date: '2022-01-03', answer: 'no' },
      { date: '2022-01-03', answer: 'no' },
      { date: '2022-01-04', answer: 'yes' },
      { date: '2022-01-04', answer: 'yes' },
      { date: '2022-01-05', answer: 'yes' },
      { date: '2022-01-05', answer: 'yes' },
      { date: '2022-01-05', answer: 'yes' },
      { date: '2022-01-05', answer: 'no' },
    ]
    
    const result = array.reduce((acc, curr) => {
      if (!acc[curr.date]) {
        acc[curr.date] = { yes: 0, no: 0 }
      }
      acc[curr.date][curr.answer]++;
      return acc;
    }, {});
    
    console.log(result)