Reputation: 71
Let's say I have this javascript array.
var events = [
{id: 1, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 2, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 2, name: 'Football Game', invitees: ['Gary', 'Jane','Bella']},
{id: 3, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 4, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 5, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 5, name: 'Football Game', invitees: ['Ted', 'Laura']},
{id: 5, name: 'Football Game', invitees: ['Jim', 'Samantha']},
];
What I need is to reduce this array to look like this:
var events = [
{id: 1, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 2, name: 'Football Game', invitees: ['Gary', 'Jane','Bella']},
{id: 3, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 4, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 5, name: 'Football Game', invitees: ['Gary', 'Jane', 'Ted', 'Laura', 'Jim', 'Samantha']}
];
Where the array has been reduced that there is only one object with each id and the invitees array within each object shows all invitees.
I'm having trouble just getting started with the basic logic here.
Upvotes: 1
Views: 39
Reputation: 350766
You could use this ES6 functional programming style code:
var result = Array.from (
events.reduce ( (acc, obj) => acc.set(obj.id,
Object.assign({}, obj, {invitees: [...new Set(
[...(acc.get(obj.id) || obj).invitees, ...obj.invitees] )]})
), new Map() ), ([id, obj]) => obj );
var events = [
{id: 1, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 2, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 2, name: 'Football Game', invitees: ['Gary', 'Jane','Bella']},
{id: 3, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 4, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 5, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 5, name: 'Football Game', invitees: ['Ted', 'Laura']},
{id: 5, name: 'Football Game', invitees: ['Jim', 'Samantha']},
];
var result = Array.from (
events.reduce ( (acc, obj) => acc.set(obj.id,
Object.assign({}, obj, {invitees: [...new Set(
[...(acc.get(obj.id) || obj).invitees, ...obj.invitees] )]})
), new Map() ), ([id, obj]) => obj );
console.log(result);
Upvotes: 0
Reputation: 122087
You can do this with reduce()
and forEach()
like this.
var events = [
{id: 1, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 2, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 2, name: 'Football Game', invitees: ['Gary', 'Jane','Bella']},
{id: 3, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 4, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 5, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 5, name: 'Football Game', invitees: ['Ted', 'Gary', 'Laura']},
{id: 5, name: 'Football Game', invitees: ['Jim', 'Samantha']}
];
var o = {}
var result = events.reduce(function(r, e) {
if (!o[e.id]) {
o[e.id] = e;
r.push(o[e.id]);
} else {
e.invitees.forEach(function(a) {
if (o[e.id].invitees.indexOf(a) == -1) o[e.id].invitees.push(a);
})
}
return r;
}, [])
console.log(result)
You could also use Set
instead of forEach()
loop to remove duplicates.
var events = [
{id: 1, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 2, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 2, name: 'Football Game', invitees: ['Gary', 'Jane','Bella']},
{id: 3, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 4, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 5, name: 'Football Game', invitees: ['Gary', 'Jane']},
{id: 5, name: 'Football Game', invitees: ['Ted', 'Gary', 'Laura']},
{id: 5, name: 'Football Game', invitees: ['Jim', 'Samantha']}
];
var o = {}
var result = events.reduce(function(r, e) {
if (!o[e.id]) {
o[e.id] = e;
r.push(o[e.id]);
} else {
o[e.id].invitees = [...new Set(o[e.id].invitees.concat(e.invitees))];
}
return r;
}, [])
console.log(result)
Upvotes: 1