0

Example:

array  = [{name:'Anna'}, {name:'Bob'}, {name:'Joe'}, {name:'Anna'}]

I need to group this array by name to get separate arrays like:

array 1 = [{name:'Anna'}, {name:'Anna'}]
array 2 = [{name:'Joe'}]
array 3 = [{name:'Bob'}]

Got no idea how to perfom this. Thanks!

Eklavya
  • 17,618
  • 4
  • 28
  • 57
Konstantin Kim
  • 209
  • 1
  • 4
  • 18
  • That's grouping, not _sorting_ – hindmost Mar 04 '19 at 13:45
  • Thats not sorting. That is filtering. Sorting means all contents of 1 bucket. You want to filter the contents of 1 bucket into others. You would need to develop a Set of values, which correlates to the number of buckets. Filter would be run a bunch of times, but you can create a more optimal solution then calling that command N time – Fallenreaper Mar 04 '19 at 13:46
  • 3
    @hindmost, sort of ... – Nina Scholz Mar 04 '19 at 13:46
  • 1
    More importantly, where is your attempt. What did you try? – Fallenreaper Mar 04 '19 at 13:47

3 Answers3

5

You mean to group the items by name I think, and not to sort them.

If this is what you want, you can create an intermediate dictionary with Array.reduce(), whose keys are the names and the values are arrays grouping all object with the same name.

Then use Object.values() to enumerate this dictionary and return all groups:

const arr = [{name:'Anna', hello: 1}, {name:'Bob'}, {name:'Joe'}, {name:'Anna'}];

const result = Object.values(arr.reduce((acc, x) => {
  acc[x.name] = [...(acc[x.name] || []), x ];
  return acc;
}, {}));

console.log(result)
jo_va
  • 13,504
  • 3
  • 23
  • 47
  • 1
    Thanks a lot. I started doing myself, but the function was much much bigger than yours. Learned a lot from your example, thanks – Konstantin Kim Mar 04 '19 at 13:52
2

Group your array by name first and then get the object values. You can use Array.reduce and Object.values for this purpose

var array  = [{name:'Anna'}, {name:'Bob'}, {name:'Joe'}, {name:'Anna'}];

const res = array.reduce((acc, item) => {
   if (acc[item.name]) {
      acc[item.name] = [...acc[item.name], item];
   } else {
      acc[item.name] = [item];
   }
   return acc;
}, {});

console.log(Object.values(res));
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
0

just convert to object based on value using reduce:

const test = array.reduce((acc, el) => {
  if (!acc[el.name]) {
    return {
       ...acc,
       [el.name]: [el]
    }
  }
  return {
    ...acc,
    [el.name]: [...acc[el.name], el]
  }
}, {});

you got an object with fields, each fields contains requested array of elements