🍇
jsでgroup byするメモ
WHY
オブジェクトのリストに対して、SQLのようにgroup byしてcountしたオブジェクトが欲しかった
HOW
- オブジェクトのパラメータにcountを追加するのではなく、ひとつ階層を増やして、
data
に元のオブジェクトを、count
にカウント数を入れるようにした。- listに渡されるオブジェクトは同じ型を持ったオブジェクトである想定
- reduceでカウントして、最後mapで整形
export const groupBy = <T, K extends keyof T>(
list: T[],
groupingField: K
): {
data: T;
count: number;
}[] => {
return (
list
// 'groupingField' のkeyで一致するobjがあったらcount up
.reduce((acc, cur) => {
const result = acc.find(
(el) => el[groupingField] === cur[groupingField]
);
if (result) {
result.count += 1;
} else {
acc.push({
...cur,
count: 1,
});
}
return acc;
}, [])
// 返り値に合わせる
.map(({ count, ...rest }) => ({
data: rest,
count,
}))
);
};
Reference
-
reduce
-
引数をジェネリクスのオブジェクト内に限定するのどうやるんだっけと思い
Discussion