Reputation: 6166
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?
Upvotes: 2
Views: 65
Reputation: 522
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.
Upvotes: 1
Reputation: 50684
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;
Upvotes: 2
Reputation: 4380
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);
Upvotes: 3