Home > Back-end >  How can we group multi-level grouping in Javascript?
How can we group multi-level grouping in Javascript?

Time:11-04

can we group array of objects in multilevel. This is my array of objects with common date and places, but different timings.

[
{
    "ID": 2104221,
    "date": "2022-11-18T00:00:00",
    "day": "18",
    "weekDay": "Fri",
    "month": "Nov",
    "Placeid": 2293,
    "Place": "AAAAAA",
    "address": "25 SSSSSS",
    "city": "RRRRR",
    "state": "WWWW",
    "Time": "8:00 PM"
},
{
    "ID": 2104344,
    "date": "2022-11-15T00:00:00",
    "day": "15",
    "weekDay": "Tue",
    "month": "Nov",
    "Placeid": 3478,
    "Place": "BIG",
    "address": "1433 The ADDDD,",
    "city": "CA",
    "state": "",
    "zipCode": "95126",
    "Time": "03:00 PM"
},
{
    "ID": 2104345,
    "date": "2022-11-15T00:00:00",
    "day": "15",
    "weekDay": "Tue",
    "month": "Nov",
    "Placeid": 3478,
    "Place": "BIG",
    "address": "1433 The ADDDD,",
    "city": "CA",
    "state": "",
    "zipCode": "95126",
    "Time": "06:00 PM"
},
{
    "ID": 2104346,
    "date": "2022-11-15T00:00:00",
    "day": "15",
    "weekDay": "Tue",
    "month": "Nov",
    "Placeid": 3478,
    "Place": "BIG",
    "address": "1433 The ADDDD,",
    "city": "CA",
    "state": "",
    "zipCode": "95126",
    "Time": "09:00 PM"
},
{
    "ID": 2104347,
    "date": "2022-11-15T00:00:00",
    "day": "15",
    "weekDay": "Tue",
    "month": "Nov",
    "Placeid": 2464,
    "Place": "ATheaters",
    "address": "2901 Capital",
    "city": "C",
    "state": "TT",
    "Time": "06:00 PM"
},
{
    "ID": 2104348,
    "date": "2022-11-15T00:00:00",
    "day": "15",
    "weekDay": "Tue",
    "month": "Nov",
    "Placeid": 2464,
    "Place": "ATheaters",
    "address": "2901 Capital",
    "city": "ANNNN",
    "state": "TT",
    "Time": "10:00 PM"
},
{
    "ID": 2103857,
    "date": "2022-11-05T16:30:00",
    "day": "5",
    "weekDay": "Sat",
    "month": "Nov",
    "Placeid": 34771,
    "Place": "Playhouse",
    "address": "525 Palace",
    "city": "BBBB",
    "state": "YYYYY",
    "Time": " 4:30 PM"
},
{
    "ID": 2103858,
    "date": "2022-11-05T23:30:00",
    "day": "5",
    "weekDay": "Sat",
    "month": "Nov",
    "Placeid": 34771,
    "Place": "Playhouse",
    "address": "525 Palace",
    "city": "BBBB",
    "state": "YYYYY",
    "Time": "11:30 PM"
},
{
    "ID": 2103862,
    "date": "2022-11-15T23:00:00",
    "day": "15",
    "weekDay": "Tue",
    "month": "Nov",
    "Placeid": 34771,
    "Place": "Playhouse",
    "address": "525 Palace",
    "city": "BBBB",
    "state": "YYYYY",
    "Time": "11:00 PM"
}

]

I would like to group based on day and places. my desired output will be

[
{
    "day": "18",
    "date": "2022-11-18T00:00:00",
    "weekDay": "Fri",
    "month": "Nov",
    "Places": [
        {
            "Placeid": 2293,
            "Place": "AAAAAA",
            "address": "25 SSSSSS",
            "city": "RRRRR",
            "state": "WWWW",
            "Timings": [
                {
                    "ID": 2104221,
                    "Time": "8:00 PM"
                }
            ]
        }
    ]
},
{
    "day": "15",
    "date": "2022-11-15T23:00:00",
    "weekDay": "Tue",
    "month": "Nov",
    "Places": [
        {
            "Placeid": 3478,
            "Place": "BIG",
            "address": "1433 The ADDDD,",
            "city": "CA",
            "state": "",
            "Timings": [
                {
                    "ID": 2104344,
                    "Time": "03:00 PM"
                },
                {
                    "ID": 2104345,
                    "Time": "06:00 PM"
                },
                {
                    "ID": 2104346,
                    "Time": "09:00 PM"
                }
            ]
        },
        {
            "Placeid": 2464,
            "Place": "ATheaters",
            "address": "2901 Capital",
            "city": "ANNNN",
            "state": "TT",
            "Timings": [
                {
                    "ID": 2104347,
                    "Time": "06:00 PM"
                },
                {
                    "ID": 2104348,
                    "Time": "10:00 PM"
                }
            ]
        },
        {
            "Placeid": 34771,
            "Place": "Playhouse",
            "address": "525 Palace",
            "city": "BBBB",
            "Timings": [
                {
                    "ID": 2103862,
                    "Time": "11:00 PM"
                }
            ]
        }
    ]
},

{
    "day": "5",
    "date": "2022-11-05T16:30:00",
    "weekDay": "Sat",
    "month": "Nov",
    "Places": [
        {
            "Placeid": 34771,
            "Place": "Playhouse",
            "address": "525 Palace",
            "city": "BBBB",
            "state": "YYYYY",
            "Timings": [
                {
                    "ID": 2103857,
                    "Time": " 4:30 PM"
                },
                {
                    "ID": 2103858,
                    "Time": "11:30 PM"
                }
            ]
        }
    ]
}
]

Is it possible to group like this using javascript? i tried with below code to group. but i didnt get my desired output.

    const MultiLevelGrouping=(data,['day','Placeid'])=>{
    var getEmpty = () => ({ _: [] }),
    result = data
      .reduce((q, o) => {
          groups
              .reduce((r, k) => {
                  const v = o[k];
                  if (!v) return r;
                  if (!r[v]) r._.push({ [k]: v, [k   'Detail']: (r[v] = getEmpty())._ });
                  return r[v];
              }, q)
              ._
              .push(o);
          return q;
      }, getEmpty())
      ._;
return result;
}

Can Someone help me out ?

CodePudding user response:

You could use 2 mapper objects. One to group each day and another to group each day-place combination. Then create entries in each mapper object if the key doesn't exists yet. Also, push the dayPlaceMap[comboKey] reference to the dayMap[day].Places array o that when the dayPlaceMap is updated, the nested array is updated.

const input = [{ID:2104221,date:"2022-11-18T00:00:00",day:"18",weekDay:"Fri",month:"Nov",Placeid:2293,Place:"AAAAAA",address:"25 SSSSSS",city:"RRRRR",state:"WWWW",Time:"8:00 PM"},{ID:2104344,date:"2022-11-15T00:00:00",day:"15",weekDay:"Tue",month:"Nov",Placeid:3478,Place:"BIG",address:"1433 The ADDDD,",city:"CA",state:"",zipCode:"95126",Time:"03:00 PM"},{ID:2104345,date:"2022-11-15T00:00:00",day:"15",weekDay:"Tue",month:"Nov",Placeid:3478,Place:"BIG",address:"1433 The ADDDD,",city:"CA",state:"",zipCode:"95126",Time:"06:00 PM"},{ID:2104346,date:"2022-11-15T00:00:00",day:"15",weekDay:"Tue",month:"Nov",Placeid:3478,Place:"BIG",address:"1433 The ADDDD,",city:"CA",state:"",zipCode:"95126",Time:"09:00 PM"},{ID:2104347,date:"2022-11-15T00:00:00",day:"15",weekDay:"Tue",month:"Nov",Placeid:2464,Place:"ATheaters",address:"2901 Capital",city:"C",state:"TT",Time:"06:00 PM"},{ID:2104348,date:"2022-11-15T00:00:00",day:"15",weekDay:"Tue",month:"Nov",Placeid:2464,Place:"ATheaters",address:"2901 Capital",city:"ANNNN",state:"TT",Time:"10:00 PM"},{ID:2103857,date:"2022-11-05T16:30:00",day:"5",weekDay:"Sat",month:"Nov",Placeid:34771,Place:"Playhouse",address:"525 Palace",city:"BBBB",state:"YYYYY",Time:" 4:30 PM"},{ID:2103858,date:"2022-11-05T23:30:00",day:"5",weekDay:"Sat",month:"Nov",Placeid:34771,Place:"Playhouse",address:"525 Palace",city:"BBBB",state:"YYYYY",Time:"11:30 PM"},{ID:2103862,date:"2022-11-15T23:00:00",day:"15",weekDay:"Tue",month:"Nov",Placeid:34771,Place:"Playhouse",address:"525 Palace",city:"BBBB",state:"YYYYY",Time:"11:00 PM"}],
      dayMap = {},
      dayPlaceMap = {};

for (const { day, date, weekDay, month, Placeid, ID, Time, ...rest } of input) {
  dayMap[day] ??= { day, date, weekDay, month, Places: [] };
  
  const comboKey = `${day}|${Placeid}`
  
  if(!dayPlaceMap[comboKey]) {
    dayPlaceMap[comboKey] ??= { Placeid, ...rest, Timings: [] }
    dayMap[day].Places.push( dayPlaceMap[comboKey] )
  }
  
  dayPlaceMap[comboKey].Timings.push({ ID, Time })
}

console.log(Object.values(dayMap))

CodePudding user response:

Here is a one-liner to do it:

const data = [{ID:2104221,date:"2022-11-18T00:00:00",day:"18",weekDay:"Fri",month:"Nov",Placeid:2293,Place:"AAAAAA",address:"25 SSSSSS",city:"RRRRR",state:"WWWW",Time:"8:00 PM"},{ID:2104344,date:"2022-11-15T00:00:00",day:"15",weekDay:"Tue",month:"Nov",Placeid:3478,Place:"BIG",address:"1433 The ADDDD,",city:"CA",state:"",zipCode:"95126",Time:"03:00 PM"},{ID:2104345,date:"2022-11-15T00:00:00",day:"15",weekDay:"Tue",month:"Nov",Placeid:3478,Place:"BIG",address:"1433 The ADDDD,",city:"CA",state:"",zipCode:"95126",Time:"06:00 PM"},{ID:2104346,date:"2022-11-15T00:00:00",day:"15",weekDay:"Tue",month:"Nov",Placeid:3478,Place:"BIG",address:"1433 The ADDDD,",city:"CA",state:"",zipCode:"95126",Time:"09:00 PM"},{ID:2104347,date:"2022-11-15T00:00:00",day:"15",weekDay:"Tue",month:"Nov",Placeid:2464,Place:"ATheaters",address:"2901 Capital",city:"C",state:"TT",Time:"06:00 PM"},{ID:2104348,date:"2022-11-15T00:00:00",day:"15",weekDay:"Tue",month:"Nov",Placeid:2464,Place:"ATheaters",address:"2901 Capital",city:"ANNNN",state:"TT",Time:"10:00 PM"},{ID:2103857,date:"2022-11-05T16:30:00",day:"5",weekDay:"Sat",month:"Nov",Placeid:34771,Place:"Playhouse",address:"525 Palace",city:"BBBB",state:"YYYYY",Time:" 4:30 PM"},{ID:2103858,date:"2022-11-05T23:30:00",day:"5",weekDay:"Sat",month:"Nov",Placeid:34771,Place:"Playhouse",address:"525 Palace",city:"BBBB",state:"YYYYY",Time:"11:30 PM"},{ID:2103862,date:"2022-11-15T23:00:00",day:"15",weekDay:"Tue",month:"Nov",Placeid:34771,Place:"Playhouse",address:"525 Palace",city:"BBBB",state:"YYYYY",Time:"11:00 PM"}]
let r = Object.values(data.reduce((a,
  {day, date, weekDay, month})=>(a[`|${day}`]??={day, date, weekDay, month,
  Places: Object.values(data.filter(i=>i.day===day).reduce((b, {
  Placeid, Place, address, city, state})=>(b[`${day}|${Placeid}`]??={
  Placeid, Place, address, city, state,
  Timings: data.filter(j=>j.day===day && j.Placeid===Placeid)
  .map(j=>({ID: j.ID, Time: j.Time}))}, b), {}))}, a), {}));
console.log(r);

  • Related