AniUI Academy

Group by several keys into a nested object

hardArrays & Objects+350 XPPractice

A report groups people by department, then by level within each department. Chaining groupBy by hand gets ugly fast, and the number of levels is often data-driven.

Implement groupByMany(items, keyFns). keyFns is an array of functions applied in order. Group the items by the first function, then group each of those groups by the second, and so on. The result is a nested plain object whose keys at each level are the string form of the keys that function returned, and whose deepest values are arrays of the original items. Items keep their original relative order inside each array, and each level's keys appear in the order those keys were first encountered. When keyFns is empty, there is nothing to group by, so return a shallow copy of items — the array itself, not an object. When items is empty and keyFns is not, return an empty object. Never modify the input.

Arguments

itemsArray
The input list to group.
keyFnsArray<(item) => any>
The grouping stack. The first function groups the items; each subsequent function groups each previous bucket.

Returns

Object | Array — A nested object one level per key function, with arrays of items at the deepest level. Returns a shallow copy of items when keyFns is empty.

Examples

groupByMany(
  [
    { d: "eng",    l: "senior", n: 1 },
    { d: "eng",    l: "junior", n: 2 },
    { d: "design", l: "senior", n: 3 },
  ],
  [(item) => item.d, (item) => item.l],
);
// {
//   eng:    { senior: [{ n: 1, ... }], junior: [{ n: 2, ... }] },
//   design: { senior: [{ n: 3, ... }] },
// }
groupByMany([1, 2, 3], []);
// [1, 2, 3] — no key functions returns a shallow copy of the array itself

What it has to do

  • Apply the key functions in order, nesting one object per level.
  • Hold arrays of the original items at the deepest level.
  • Use the string form of each key function's return value as the object key.
  • Return a shallow copy of items when keyFns is empty.
  • Preserve the original item order within each group, and do not mutate the input.

Stuck? The javascript course covers everything this challenge needs.

Try it yourself
Loading playground...
5 tests · +350 XP

Discussion

Sign in to post
Sign in to join the conversation.Sign in

No comments yet. Be the first to say something.