Syntle
Syntle

Reputation: 5174

Grouping object entries into object arrays

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

Answers (4)

muasif80
muasif80

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

Chrome Console Output

We have a similar question here Most efficient method to groupby on an array of objects

Upvotes: 0

Mark Colby
Mark Colby

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

user120242
user120242

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

Majed Badawi
Majed Badawi

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

Related Questions