🌐
Code Snippet — July 9, 2026GroupBy Utility — Group Any Array by Key, Nested Path, or Function (JS)Stop rewriting
arr.reduce((acc, item) => { ... }, {}) in every file. This ~35-line utility handles string keys, dot-notation paths (
"address.city"), custom functions, null handling, and Map mode.
function getNestedValue(obj, path) {
return path.split('.').reduce((cur, key) => {
if (cur === null || cur === undefined) return undefined;
return cur[key];
}, obj);
}
function groupBy(array, groupingKey, options = {}) {
const { asMap = false } = options;
const collector = asMap ? new Map() : {};
const resolveGroup = (item) => {
if (typeof groupingKey === 'function') return groupingKey(item);
if (typeof groupingKey === 'string') {
const v = getNestedValue(item, groupingKey);
return (v === null || v === undefined) ? '__null__' : String(v);
}
throw new TypeError('groupBy key must be a string or function');
};
for (const item of array) {
const group = resolveGroup(item);
if (asMap) {
if (!collector.has(group)) collector.set(group, []);
collector.get(group).push(item);
} else {
if (!collector[group]) collector[group] = [];
collector[group].push(item);
}
}
return collector;
}
// Bonus: countBy in one line
const countBy = (arr, key) =>
Object.fromEntries(
Object.entries(groupBy(arr, key)).map(([k, v]) => [k, v.length])
);
Usage:groupBy(users, 'department') // Simple key
groupBy(orders, 'shipping.address.country') // Dot-notation
groupBy(items, i => i.price > 100 ? 'premium' : 'standard') // Function
groupBy(items, 'category', { asMap: true }) // Returns Map
countBy(orders, 'status') // → { pending: 3, shipped: 2, ... }
💡
Array.prototype.groupBy() is coming to native JS in 2026, but this works today in every environment with bonus features.