Multi level group on array of objects in Vanilla JS

Tags:



So I have an array of objects that I am trying to group together, I’m still kinda new to JS, getting better as I practice more and more but not great yet, anyway I’m trying to figure out how to group at multiple levels. For example if I have a group of theme parks that I wanted to group by state and then city. I can get the group by state, I can get the group by city, but I’m a little lost on group by state and city.

let parks = [{
    id: 546,
    name: "Kalahari Resorts",
    city: "Wisconsin Dells",
    state: "Wisconsin",
    country: "United States"
  },
  {
    id: 547,
    name: "Little Amerricka",
    city: "Marshall",
    state: "Wisconsin",
    country: "United States"
  },
  {
    id: 2,
    name: "Calaway Park",
    city: "Calgary",
    state: "Alberta",
    country: "Canada"
  }
];

function groupBy(objectArray, property) {
  return objectArray.reduce((acc, obj) => {
    const key = obj[property];
    if (!acc[key]) {
      acc[key] = [];
    }
    acc[key].push(obj);
    return acc;
  }, {});
}

let group = groupBy(parks, 'state');
console.log(group);

But what I want to do is have it first group everything by state, which the above does, and then group by city, and I’m trying to do this without libraries, just plain Vanilla JS

So I should get

{
  Alberta: Calgary: []
}, {
  Wisconsin: Wisconsin Dells: [],
  Marshall: []
}

Answer

You can just reuse your groupBy function here:

let group = groupBy(parks, 'state');
Object.keys(group).forEach(stateKey => {
  group[stateKey] = groupBy(group[stateKey], 'city');

  // For further grouping, just make sure you pass in an array
  // as the first argument to groupBy. 
  Object.keys(group[stateKey]).forEach(cityKey => {
    group[stateKey][cityKey] = groupBy(group[stateKey][cityKey], 'county');
  });
});


Source: stackoverflow