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.
Kept this one simple — just loop through once and build it up as you go:
function groupBy(items, key) {
const grouped = new Map();
for (const item of items) {
const group = Reflect.get(item, key);
if (!grouped.has(group)) {
grouped.set(group, new Array());
}
grouped.get(group).push(item);
}
return Object.fromEntries(grouped);
}
Nothing fancy, but it does the job. I used a Map while building it up, then converted back to a plain object at the end. The input array stays untouched since we’re only reading from it and pushing into fresh arrays, and the items keep their original order inside each group.
Why:
The reduce method is used to accumulate the results into a new object. For each item, its value for the specified key is used as the group identifier. If a group does not yet exist, an empty array is created for it before the current item is pushed into that group’s array.
So groupBy(users, ‘address.city’) walks down to the city before grouping. One edge worth calling out: if something’s missing an address entirely, optional chaining gives you undefined and those all land in one group together — which is honest, but you’d want to decide that’s what you actually want rather than discovering it later.