Coding Challenge - #33: Group By Key

Write groupBy(items, key) that returns an object grouping the array of objects by the given property. groupBy([{t:"a",v:1},{t:"b",v:2},{t:"a",v:3}], "t") should give {a:[{t:"a",v:1},{t:"a",v:3}], b:[{t:"b",v:2}]}.

function groupBy(items, key) {
  // your code here
}

Rules:

  • Plain JavaScript, no libraries
  • Do not mutate the input array

Post your solution as a reply. Answer goes up in about a day.

You can use reduce() to group the items by the selected property without modifying the original array:

function groupBy(items, key) {
  return items.reduce((groups, item) => {
    const value = item[key];

    if (!Object.hasOwn(groups, value)) {
      groups[value] = [];
    }

    groups[value].push(item);
    return groups;
  }, {});
}

This keeps the original order of items within each group and runs in O(n) time on average. Object.hasOwn() also avoids treating inherited object properties as existing groups.

okay so, solid reduce pattern there! love seeing Object.hasOwn for the win too. we’ll see how it stacks up when the solution drops later today!

Challenge solution: The task requires grouping an array of objects by a specified key into a new object where keys are the unique values of the grouping property and values are arrays of matching objects.

One way to do it:

function groupBy(items, key) {
  return items.reduce((accumulator, currentItem) => {
    const groupValue = currentItem[key];
    if (!accumulator[groupValue]) {
      accumulator[groupValue] = [];
    }
    accumulator[groupValue].push(currentItem);
    return accumulator;
  }, {});
}

Why:
This solution uses the Array.prototype.reduce method to iterate over the input array. For each item, it determines the grouping key’s value and adds the item to the corresponding array in the accumulator object. If a group does not yet exist, it is initialized as an empty array before pushing the current item.


Got it: @Apexcodes :trophy:

First-answer leaderboard

  1. @emmawalter5 - 13 (firsts) :trophy:
  2. @Apexcodes - 9 (firsts)
  3. @kirupa - 8 (firsts)
  4. @adnanahmed - 2 (firsts)

Nice one, Apexcodes — the Object.hasOwn check is the part I liked most. A lot of people would just do groups[value] || [], which works until a key like ‘toString’ or ‘constructor’ shows up and suddenly you’re reading off the prototype instead of starting a fresh group.

Your version also keeps the input untouched and keeps items in order inside each group, which is exactly what the challenge asked for.

One thing I’d watch for: if a key value is missing or undefined, everything without that property ends up lumped under one ‘undefined’ group. That’s not wrong for this challenge, but in real code I’d probably decide up front whether those items should be skipped or grouped separately, just so it doesn’t surprise you later.