Home > OS >  How do I group together identical items when mapping over an array of objects?
How do I group together identical items when mapping over an array of objects?

Time:12-19

Given the following array of gigs:

const gigs = [
  {
    name: ' sat gig 1',
    date: 'Sat Dec 10 2022'
  },
  {
    name: ' sat gig 2',
    date: 'Sat Dec 10 2022'
  },
  {
    name: ' sun gig 1',
    date: 'Sun Dec 11 2022'
  },
  {
    name: ' sun gig 2',
    date: 'Sun Dec 11 2022'
  },  
]

How do I map over it and render the gigs, but grouped by the gig date? I've included the desired output as follows, as well as my own attempt to solve this. I'd prefer to not use lodash.

Sat Dec 10 
sat gig 1
sat gig 2

Sun Dec 11
sun gig 1
sun gig 2

Here's my attempt so far:

const gigs = [
  {
    name: ' sat gig 1',
    date: '2022-12-10'
  },
  {
    name: ' sat gig 2',
    date: '2022-12-10'
  },
  {
    name: ' sun gig 1',
    date: '2022-12-11'
  },
  {
    name: ' sun gig 2',
    date: '2022-12-11'
  },  
]

const gigArray =[]
gigs.map(gig => {
  const gigDate = new Date(gig.date)
  const gigDateString = gigDate.toString().slice(0,15) //gives date in form 'Sun Dec 11 2022'
  gigArray.push({date:gigDateString,name:gig.name})
})

  const groupedObj = gigArray.reduce(
    (prev, current) => ({
      ...prev,
      [current]: [...(prev[current] || []), current],
    }),
    {}
  );

const groupedObjToArr = Object.values(groupedObj);

CodePudding user response:

Here's a reduce solution that creates an object with the dates as the keys:

const gigs=[{name:"sat gig 1",date:"Sat Dec 10 2022"},{name:"sat gig 2",date:"Sat Dec 10 2022"},{name:"sun gig 1",date:"Sun Dec 11 2022"},{name:"sun gig 2",date:"Sun Dec 11 2022"}];

const result = gigs.reduce((acc, curr) => {
  if (acc[curr.date]) {
    acc[curr.date].push(curr)
  } else {
    acc[curr.date] = [curr]
  }
  return acc;
}, {})

console.log(result)

From there, generating the output is simple:

const gigs=[{name:"sat gig 1",date:"Sat Dec 10 2022"},{name:"sat gig 2",date:"Sat Dec 10 2022"},{name:"sun gig 1",date:"Sun Dec 11 2022"},{name:"sun gig 2",date:"Sun Dec 11 2022"}];

const result = gigs.reduce((acc, curr) => {
  if (acc[curr.date]) {
    acc[curr.date].push(curr)
  } else {
    acc[curr.date] = [curr]
  }
  return acc;
}, {})

Object.keys(result).forEach(key => {
  console.log(key)
  result[key].forEach(val => console.log(val))
})

  • Related