2

I am trying to dynamically split an array of objects into groups based on values of a property.

Here is an example of the input:

`input = [
    {"name": "john", "location": "first"},
    {"name": "steve", "location": "first"},
    {"name": "paul", "location": "another"},
    {"name": "tony", "location": "random"},
    {"name": "ant", "location": "random"}
]`

and the desired output:

`solution(input, location) = [
    first:   [{"name": "john", "location": "first"},
              {"name": "steve", "location": "first"}],
    another: [{"name": "paul", "location": "another"}],
    random:  [{"name": "tony", "location": "random"},
              {"name": "ant", "location": "random"}]
]`

I do not know the values that location can be (but i do know the key name)

I am trying to avoid using any external libs, (this is inside an angular 5 project) but if it makes it drastically easier then I am not against it.

Thanks in advance

Nicholas Foden
  • 156
  • 3
  • 12

1 Answers1

11

Use Array#reduce for that:

const input = [{"name":"john","location":"first"},{"name":"steve","location":"first"},{"name":"paul","location":"another"},{"name":"tony","location":"random"},{"name":"ant","location":"random"}];

const group = input.reduce((acc, item) => {
  if (!acc[item.location]) {
    acc[item.location] = [];
  }

  acc[item.location].push(item);
  return acc;
}, {})

console.log(group);

Edit 1

If you want to iterate on the result, you can use for...of loop with Object.entries like this:

for (let [location, persons] of Object.entries(group)) {
  console.log(location, persons);
  // do your stuff here
}
31piy
  • 23,323
  • 6
  • 47
  • 67
  • Thankyou! that was super quick.. Ive been struggling to get my head round map and reduce but this has helped ! – Nicholas Foden Apr 26 '18 at 15:02
  • I have just noticed that the result of this answer is not an array but an object. I would like to create an array containing the result so I can iterate over it... – Nicholas Foden Apr 27 '18 at 11:20