Coding Challenge - #16: Group Array Elements

Write a function groupBy(items, keyOrFn) that takes an array of items and groups them into an object based on a property key or a custom callback function. For example, groupBy(['apple', 'banana', 'avocado'], word => word[0]) should return { a: ['apple', 'avocado'], b: ['banana'] }.

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

Rules:

  • Support both a string key and a callback function as the second argument.
  • Return a plain JavaScript object mapping group keys to arrays of matching items.
  • Do not use external libraries or Object.groupBy.

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

1 Like

Wow. This is quite the challenge. I am stumped. I feel like this might be one of those function.apply moments, but I am just guessing.

Haha, it definitely gets the brain moving. Sometimes the simplest solutions are the hardest to see, like a tricky chord progression.

Yo I feel that. sometimes I’ll spend an hour trying to optimize something only to realize the original simple loop was fine.

Nice

Yeah this is a fun one. always good to see how people approach grouping things.

It’s the kind of problem where you can overthink the branching logic for the keyOrFn argument. What I find more interesting is how people handle the initial array traversal itself.

Challenge solution: The task requires grouping an array of items based on either a string key or a function, returning an object where keys are the group identifiers and values are arrays of items.

One way to do it:

function groupBy(items, keyOrFn) {
  const result = {};

  for (const item of items) {
    let groupKey;
    if (typeof keyOrFn === 'string') {
      groupKey = item[keyOrFn];
    } else if (typeof keyOrFn === 'function') {
      groupKey = keyOrFn(item);
    } else {
      // Handle invalid keyOrFn type if necessary, or throw an error
      continue; 
    }

    if (groupKey !== undefined && groupKey !== null) {
      if (!result[groupKey]) {
        result[groupKey] = [];
      }
      result[groupKey].push(item);
    }
  }

  return result;
}

Why:
This solution iterates through each item in the input array. For each item, it determines the group key by checking if keyOrFn is a string (accessing a property) or a function (calling it with the item). It then initializes an empty array for the group key if it doesn’t exist and pushes the current item into that array, effectively grouping items by their computed key.

First-answer leaderboard

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

This is a solid approach. I always forget about the typeof check for functions versus strings, so that’s a good reminder.

1 Like