简体   繁体   中英

Combine data from an array of objects based on one of them

Having an array of objects like this:

[{"event_id":1,"person":"John"},
 {"event_id":2,"person":"John"},
 {"event_id":3,"person":"Mike"},
 {"event_id":1,"person":"Mike"},
 {"event_id":1,"person":"Anna"},
 {"event_id":3,"person":"Anna"}]

the wanted result should combine them based on the event_id and show them in a table structure like this:

1 John, Mike, Ana
2 John
3 Mike, Anna

Each row represents an event and the rows contains the people who participated in that event. I don't know how do to this in JavaScript. Any suggestions?

You can use reduce :

 const data = [ { event_id: 1, person: 'John' }, { event_id: 2, person: 'John' }, { event_id: 3, person: 'Mike' }, { event_id: 1, person: 'Mike' }, { event_id: 1, person: 'Anna' }, { event_id: 3, person: 'Anna' }, ]; const result = data.reduce( (acc, val) => ({...acc, [val.event_id]: acc[val.event_id]? [...acc[val.event_id], val.person]: [val.person], }), {}, ); console.log(result);

You can use a Map with .reduce() to first group your objects, where the event_id is the key in the map, and the value is an array of accumulated person values for the same event_id values. You can then use Array.from() to map each [key, value] entry to a string of HTML for the table rows and data. You can then add this string to your HTML like so:

 const arr = [{"event_id":1,"person":"John"}, {"event_id":2,"person":"John"}, {"event_id":3,"person":"Mike"}, {"event_id":1,"person":"Mike"}, {"event_id":1,"person":"Anna"}, {"event_id":3,"person":"Anna"}]; const table = ` <table> ${Array.from( arr.reduce((m, {event_id:id, person}) => m.set(id, [...(m.get(id) || []), person]), new Map), ([key, arr]) => `<tr><td>${key}</td><td>${arr.join(', ')}</td></tr>` ).join('')} </table> `; document.body.innerHTML = table;

I recommend you to use Map data type.

Map is a collection of keyed data items, just like an Object. But the main difference is that Map allows keys of any type. First of all we iterate on Array of Objects, then we check if there is any event_id in Map we push Object.person to the value of event_id entry:

const listOfObjects = [
    { "event_id": 1, "person": "John" },
    { "event_id": 2, "person": "John" },
    { "event_id": 3, "person": "Mike" },
    { "event_id": 1, "person": "Mike" },
    { "event_id": 1, "person": "Anna" },
    { "event_id": 3, "person": "Anna" }];
let eventIdCollection = new Map();
listOfObjects.forEach(obj => {
    if (eventIdCollection.has(obj.event_id)) {
        let persons = eventIdCollection.get(obj.event_id);
        persons.push(obj.person);
        eventIdCollection.set(obj.event_id, persons);
    }
    else {
        eventIdCollection.set(obj.event_id, [obj.person]);
    }
});

the result is Map of event_id to Array of persons.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM