Home > database >  Grouping an array of objects in Javascript
Grouping an array of objects in Javascript

Time:06-15

I get an array of objects from an API in the format shown below:

[
   {
      "participant_details":[
         {
            "participant_id":2,
            "participant_name":"Bond James"
         },
         {
            "participant_id":3,
            "participant_name":"Barkley Charles"
         }
      ],
      "schedule_details":{
         "schedule_id":17,
         "schedule_name":"bug test",
         "job_type":"Registered Nurse",
         "schedule_type":"Shared/Grouped Schedule",
         "number_of_shifts":10,
         "start_date":"2022-05-30 23:00:00",
         "end_date":"2022-06-03 06:00:00"
      }
   },
   {
      "participant_details":[
         {
            "participant_id":3,
            "participant_name":"Barkley Charles"
         }
      ],
      "schedule_details":{
         "schedule_id":18,
         "schedule_name":"June Chuk Schedule",
         "job_type":"Coordinator - Operations",
         "schedule_type":"Individual Schedule",
         "number_of_shifts":6,
         "start_date":"2022-06-02 09:00:00",
         "end_date":"2022-06-07 15:00:00"
      }
   },
   {
      "participant_details":[
         {
            "participant_id":2,
            "participant_name":"Bond James"
         },
         {
            "participant_id":3,
            "participant_name":"Barkley Charles"
         }
      ],
      "schedule_details":{
         "schedule_id":19,
         "schedule_name":"Grouped Re-assignment test",
         "job_type":"People & Culture",
         "schedule_type":"Shared/Grouped Schedule",
         "number_of_shifts":6,
         "start_date":"2022-06-04 19:00:00",
         "end_date":"2022-06-10 02:00:00"
      }
   }
]

The property participant_details contains information about the participants that are attached to the schedule in the property: schedule_details

My question is if there is any way possible to group this data by a participant so that the end result has the schedule_details grouped into an array of objects by participant, somehing that looks like this:

[
   {
      "participant_id":2,
      "participant_name":"Bond James",
      "schedule_details":[
         {
            "schedule_id":17,
            "schedule_name":"bug test",
            "job_type":"Registered Nurse",
            "schedule_type":"Shared/Grouped Schedule",
            "number_of_shifts":10,
            "start_date":"2022-05-30 23:00:00",
            "end_date":"2022-06-03 06:00:00"
         },
         {
            "schedule_id":19,
            "schedule_name":"Grouped Re-assignment test",
            "job_type":"People & Culture",
            "schedule_type":"Shared/Grouped Schedule",
            "number_of_shifts":6,
            "start_date":"2022-06-04 19:00:00",
            "end_date":"2022-06-10 02:00:00"
         }
      ]
   },
   {
      "participant_id":3,
      "participant_name":"Barkley Charles",
      "schedule_details":[
         {
            "schedule_id":17,
            "schedule_name":"bug test",
            "job_type":"Registered Nurse",
            "schedule_type":"Shared/Grouped Schedule",
            "number_of_shifts":10,
            "start_date":"2022-05-30 23:00:00",
            "end_date":"2022-06-03 06:00:00"
         },
         {
            "schedule_id":18,
            "schedule_name":"June Chuk Schedule",
            "job_type":"Coordinator - Operations",
            "schedule_type":"Individual Schedule",
            "number_of_shifts":6,
            "start_date":"2022-06-02 09:00:00",
            "end_date":"2022-06-07 15:00:00"
         },
         {
            "schedule_id":19,
            "schedule_name":"Grouped Re-assignment test",
            "job_type":"People & Culture",
            "schedule_type":"Shared/Grouped Schedule",
            "number_of_shifts":6,
            "start_date":"2022-06-04 19:00:00",
            "end_date":"2022-06-10 02:00:00"
         }
      ]
   }
]

CodePudding user response:

You could key the data by participant id in a Map, and give each key an object that has the participant info and an empty schedule array.

Then iterate the data to populate those schedule arrays based on the participant id.

Finally extract the values from the map:

const data = [{"participant_details":[{"participant_id":2,"participant_name":"Bond James"},{"participant_id":3,"participant_name":"Barkley Charles"}],"schedule_details":{"schedule_id":17,"schedule_name":"bug test","job_type":"Registered Nurse","schedule_type":"Shared/Grouped Schedule","number_of_shifts":10,"start_date":"2022-05-30 23:00:00","end_date":"2022-06-03 06:00:00"}},{"participant_details":[{"participant_id":3,"participant_name":"Barkley Charles"}],"schedule_details":{"schedule_id":18,"schedule_name":"June Chuk Schedule","job_type":"Coordinator - Operations","schedule_type":"Individual Schedule","number_of_shifts":6,"start_date":"2022-06-02 09:00:00","end_date":"2022-06-07 15:00:00"}},{"participant_details":[{"participant_id":2,"participant_name":"Bond James"},{"participant_id":3,"participant_name":"Barkley Charles"}],"schedule_details":{"schedule_id":19,"schedule_name":"Grouped Re-assignment test","job_type":"People & Culture","schedule_type":"Shared/Grouped Schedule","number_of_shifts":6,"start_date":"2022-06-04 19:00:00","end_date":"2022-06-10 02:00:00"}}];

const map = new Map(data.flatMap((o) => o.participant_details.map(o => 
    [o.participant_id, { ...o, schedule_details: [] }]
)));

for (const o of data) {
    for (const {participant_id} of o.participant_details) {
        map.get(participant_id).schedule_details.push({...o.schedule_details});
    }
}

const result = [...map.values()];
console.log(result);

CodePudding user response:

Here you go:

const input=[{participant_details:[{participant_id:2,participant_name:"Bond James"},{participant_id:3,participant_name:"Barkley Charles"}],schedule_details:{schedule_id:17,schedule_name:"bug test",job_type:"Registered Nurse",schedule_type:"Shared/Grouped Schedule",number_of_shifts:10,start_date:"2022-05-30 23:00:00",end_date:"2022-06-03 06:00:00"}},{participant_details:[{participant_id:3,participant_name:"Barkley Charles"}],schedule_details:{schedule_id:18,schedule_name:"June Chuk Schedule",job_type:"Coordinator - Operations",schedule_type:"Individual Schedule",number_of_shifts:6,start_date:"2022-06-02 09:00:00",end_date:"2022-06-07 15:00:00"}},{participant_details:[{participant_id:2,participant_name:"Bond James"},{participant_id:3,participant_name:"Barkley Charles"}],schedule_details:{schedule_id:19,schedule_name:"Grouped Re-assignment test",job_type:"People & Culture",schedule_type:"Shared/Grouped Schedule",number_of_shifts:6,start_date:"2022-06-04 19:00:00",end_date:"2022-06-10 02:00:00"}}];

console.log(mapResultByParticipant(input));

function mapResultByParticipant(events) {
    const participants = {};

    events.map((event) => {
      
      //if we don't have such participant - create him
      event.participant_details.map((participant) => {
        if (!participants[participant.participant_id]) {
          participants[participant.participant_id] = {
            ...participant,
            schedule_details: []
          }
        }

        // add event to participant
        participants[participant.participant_id].schedule_details.push(event.schedule_details);
      });
    });

    return Object.values(participants);
}

CodePudding user response:

var x = [
   {
      "participant_details":[
         {
            "participant_id":2,
            "participant_name":"Bond James"
         },
         {
            "participant_id":3,
            "participant_name":"Barkley Charles"
         }
      ],
      "schedule_details":{
         "schedule_id":17,
         "schedule_name":"bug test",
         "job_type":"Registered Nurse",
         "schedule_type":"Shared/Grouped Schedule",
         "number_of_shifts":10,
         "start_date":"2022-05-30 23:00:00",
         "end_date":"2022-06-03 06:00:00"
      }
   },
   {
      "participant_details":[
         {
            "participant_id":3,
            "participant_name":"Barkley Charles"
         }
      ],
      "schedule_details":{
         "schedule_id":18,
         "schedule_name":"June Chuk Schedule",
         "job_type":"Coordinator - Operations",
         "schedule_type":"Individual Schedule",
         "number_of_shifts":6,
         "start_date":"2022-06-02 09:00:00",
         "end_date":"2022-06-07 15:00:00"
      }
   },
   {
      "participant_details":[
         {
            "participant_id":2,
            "participant_name":"Bond James"
         },
         {
            "participant_id":3,
            "participant_name":"Barkley Charles"
         }
      ],
      "schedule_details":{
         "schedule_id":19,
         "schedule_name":"Grouped Re-assignment test",
         "job_type":"People & Culture",
         "schedule_type":"Shared/Grouped Schedule",
         "number_of_shifts":6,
         "start_date":"2022-06-04 19:00:00",
         "end_date":"2022-06-10 02:00:00"
      }
   }
];

var result = [];
for (const o of x) {
    if (o.participant_details.length === 0) {
        continue;
    }
    var newObj = {};
    for (const p of o.participant_details) {
        var index = result.findIndex((value) => value.participant_id === p.participant_id && value.participant_name === p.participant_name);
        if (index !== -1) {
            result[index].schedule_details.push(o.schedule_details);
        } else {
            result.push({
                participant_id: p.participant_id,
                participant_name: p.participant_name,
                schedule_details: [
                    o.schedule_details
                ],
            });
        }
    }
}
console.log("%o", result);

CodePudding user response:

You can use Array.reduce() to get the desired result.

We'd call .reduce() once on the input array, then also on the participant_details array for each input.

Once we've grouped the schedule_details, we'll convert to an array again with Object.values()

const input = [ { "participant_details":[ { "participant_id":2, "participant_name":"Bond James" }, { "participant_id":3, "participant_name":"Barkley Charles" } ], "schedule_details":{ "schedule_id":17, "schedule_name":"bug test", "job_type":"Registered Nurse", "schedule_type":"Shared/Grouped Schedule", "number_of_shifts":10, "start_date":"2022-05-30 23:00:00", "end_date":"2022-06-03 06:00:00" } }, { "participant_details":[ { "participant_id":3, "participant_name":"Barkley Charles" } ], "schedule_details":{ "schedule_id":18, "schedule_name":"June Chuk Schedule", "job_type":"Coordinator - Operations", "schedule_type":"Individual Schedule", "number_of_shifts":6, "start_date":"2022-06-02 09:00:00", "end_date":"2022-06-07 15:00:00" } }, { "participant_details":[ { "participant_id":2, "participant_name":"Bond James" }, { "participant_id":3, "participant_name":"Barkley Charles" } ], "schedule_details":{ "schedule_id":19, "schedule_name":"Grouped Re-assignment test", "job_type":"People & Culture", "schedule_type":"Shared/Grouped Schedule", "number_of_shifts":6, "start_date":"2022-06-04 19:00:00", "end_date":"2022-06-10 02:00:00" } } ]

const result = Object.values(input.reduce((acc, { participant_details, schedule_details }) => { 
    return participant_details.reduce((acc, { participant_id, participant_name }) => { 
        acc[participant_id] = acc[participant_id] || { participant_id, participant_name, schedule_details: [] };
        acc[participant_id].schedule_details.push(schedule_details);
        return acc;
    }, acc);
}, {}))

console.log('Result:', JSON.stringify(result, null, 2));
.as-console-wrapper { max-height: 100% !important; }

CodePudding user response:

You can use a combinaison of 'map' and 'forEach' on your objects array

// objects contains your API result
var objects = [...]
// 1 - Get array of objects where each object has a list of participants
var result = objects.map(obj=>{
  var participants = obj["participant_details"].map(participant=>{
    return {
      "participant_id":participant["participant_id"],
      "participant_name":participant["participant_name"],
      "schedule_details":obj["schedule_details"]
    }
  })
  return {
    "participants": participants
  }
})

// 2 - Compose the final result by pushing every participant in new array
var finalResult = []
result.forEach(obj=>{
   obj["participants"].forEach(p=>{
     finalResult.push(p)
   })
})
console.log(finalResult)
  • Related