🍇

jsでgroup byするメモ

2021/09/23に公開

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

Discussion