Implement groupBy
Write groupBy(arr, keyFnOrPropName) that groups the items of arr into a plain object. If the second argument is a function, call it with each item to get that item's group key; if it is a string, use that property of each item as the key.
groupBy([6.1, 4.2, 6.3], Math.floor)→{ 4: [4.2], 6: [6.1, 6.3] }groupBy(['one', 'two', 'three'], 'length')→{ 3: ['one', 'two'], 5: ['three'] }groupBy(users, 'role')→{ admin: [...], guest: [...] }groupBy([], (x) => x)→{}
Items keep their original order within each group. Return an ordinary object created with {}, and make sure keys that clash with built-in object properties, like 'constructor' or 'toString', still work.
Define groupBy in the editor. 7 tests will call it.
Hint 1Normalise the second argument into a function first: if it's a string, use item => item[name].
Hint 2Loop over the items, compute each key, and push the item into result[key], creating the array the first time you see that key.
Hint 3Check for an existing group with Object.hasOwn(result, key) or Object.prototype.hasOwnProperty.call(result, key). A truthiness check like if (!result[key]) breaks for 'constructor', which every object inherits.
one clean solution
function groupBy(arr, keyFnOrPropName) {
const getKey =
typeof keyFnOrPropName === 'function'
? keyFnOrPropName
: (item) => item[keyFnOrPropName];
const groups = {};
for (const item of arr) {
const key = getKey(item);
if (!Object.prototype.hasOwnProperty.call(groups, key)) groups[key] = [];
groups[key].push(item);
}
return groups;
}