Reputation: 5174
How can I create arrays to group members depending on their tag
?
Tags can be anything, these are just examples.
Example Input
[
{ tag: 'Red', member: 'Red-Steve' },
{ tag: 'Red', member: 'Red-Adam' },
{ tag: 'Blue', member: 'Blue-John' },
{ tag: 'Blue', member: 'Blue-James' },
{ tag: 'Blue', member: 'Blue-Igor' }
]
Example Output
{
Red: ['Red-Steve', 'Red-Adam']
Blue: ['Blue-John', 'Blue-James', 'Blue-Igor']
}
Edit: I just made a test case on jsperf
to compare the efficiency of the different answers and also the answer from the suggested duplicate question
https://jsperf.com/group-objects-reduce-vs-for-loop
The answer by @Majed Badawi was the most efficient
Upvotes: 0
Views: 75
Reputation: 6006
I think this will be a good way of achieving it in modern syntax. But may be there are some aggregate functions too.
var arr = [
{ tag: 'Red', member: 'Red-Steve' },
{ tag: 'Red', member: 'Red-Adam' },
{ tag: 'Blue', member: 'Blue-John' },
{ tag: 'Blue', member: 'Blue-James' },
{ tag: 'Blue', member: 'Blue-Igor' }
];
var newArr = [];
arr.forEach(o => {
var existing = newArr[o.tag] && newArr[o.tag].length > 0 ? newArr[o.tag] : [];
newArr[o.tag] = [...existing, ...[o.member]];
});
console.log('newArr', newArr);
In Chrome it is giving following output in the console
We have a similar question here Most efficient method to groupby on an array of objects
Upvotes: 0
Reputation: 191
The following code will do what you ask. It uses the object[variableKey] syntax to get what you are looking for.
const members=[
{ tag: 'Red', member: 'Red-Steve' },
{ tag: 'Red', member: 'Red-Adam' },
{ tag: 'Blue', member: 'Blue-John' },
{ tag: 'Blue', member: 'Blue-James' },
{ tag: 'Blue', member: 'Blue-Igor' }
]
//this will be the output object
const newObj={};
for(memberObj of members){
const newKey = memberObj.tag;
//if the key already existed, just add the new item to the existing array
if(newObj[newKey]){newObj[newKey].push(memberObj.member);}
//if the key didn't exist, create an array value for it with the new object
else{newObj[newKey]=[memberObj.member];}
}
console.log(newObj);
Upvotes: 1
Reputation: 15268
collect into object map using tag as key and appending to an array
d=[
{ tag: 'Red', member: 'Red-Steve' },
{ tag: 'Red', member: 'Red-Adam' },
{ tag: 'Blue', member: 'Blue-John' },
{ tag: 'Blue', member: 'Blue-James' },
{ tag: 'Blue', member: 'Blue-Igor' }
]
console.log(
d.reduce((acc,{tag,member})=>({...acc, [tag]: [...acc[tag]||[], member]}),{})
)
Upvotes: 1
Reputation: 28414
You can use a simple set
to group them by tag
as follows:
let list = [
{ tag: 'Red', member: 'Red-Steve' },
{ tag: 'Red', member: 'Red-Adam' },
{ tag: 'Blue', member: 'Blue-John' },
{ tag: 'Blue', member: 'Blue-James' },
{ tag: 'Blue', member: 'Blue-Igor' }
];
let set = {};
for(let i = 0; i < list.length; i++){
let current = list[i];
if(!set[current.tag])
set[current.tag] = [current.member];
else
set[current.tag].push(current.member);
}
console.log(set);
Upvotes: 1