I struggled finding the solution I was looking for in other stackoverflow posts, even though I strongly feel as if it must exist. If it does, please do forward me in the rig
You could take a dynamic approach by using a Map and generate all items after collecting the unknown keys.
function groupBy(array, key) {
return Array.from(
array.reduce((m, o) => {
var temp = m.get(o[key]);
if (!temp) {
m.set(o[key], temp = {});
}
Object.entries(o).forEach(([k, v]) => {
if (k === key) {
return;
}
temp[k] = temp[k] || { sum: 0, count: 0 };
temp[k].sum += v;
temp[k].count++;
});
return m;
}, new Map),
([k, v]) => Object.assign({ [key]: k }, ...Object.entries(v).map(([l, { sum, count }]) => ({ [l]: +(sum / count).toFixed(1) })))
);
}
const myData = [{ team: "GSW", pts: 120, ast: 18, reb: 11 }, { team: "GSW", pts: 125, ast: 28, reb: 18 }, { team: "GSW", pts: 110, ast: 35, reb: 47 }, { team: "HOU", pts: 100, ast: 17, reb: 43 }, { team: "HOU", pts: 102, ast: 14, reb: 32 }, { team: "SAS", pts: 127, ast: 21, reb: 25 }, { team: "SAS", pts: 135, ast: 25, reb: 37 }, { team: "SAS", pts: 142, ast: 18, reb: 27 }];
console.log(groupBy(myData, 'team'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
With rest properties (babel: true
).
function groupBy(array, key) {
return Array.from(
array.reduce((m, { [key]: k, ...rest}) => {
var temp = m.get(k);
if (!temp) {
m.set(k, temp = {});
}
Object.entries(rest).forEach(([l, v]) => {
temp[l] = temp[l] || { sum: 0, count: 0 };
temp[l].sum += v;
temp[l].count++;
});
return m;
}, new Map),
([k, v]) => Object.assign({ [key]: k }, ...Object.entries(v).map(([l, { sum, count }]) => ({ [l]: +(sum / count).toFixed(1) })))
);
}
const myData = [{ team: "GSW", pts: 120, ast: 18, reb: 11 }, { team: "GSW", pts: 125, ast: 28, reb: 18 }, { team: "GSW", pts: 110, ast: 35, reb: 47 }, { team: "HOU", pts: 100, ast: 17, reb: 43 }, { team: "HOU", pts: 102, ast: 14, reb: 32 }, { team: "SAS", pts: 127, ast: 21, reb: 25 }, { team: "SAS", pts: 135, ast: 25, reb: 37 }, { team: "SAS", pts: 142, ast: 18, reb: 27 }];
console.log(groupBy(myData, 'team'));
.as-console-wrapper { max-height: 100% !important; top: 0; }