動かざることバグの如し

近づきたいよ 君の理想に

TypeScriptで配列をグルーピングするgroupBy関数

やりたいこと

JSONとかのJavaScriptオブジェクトの配列があったとき、特定のキーとかでグルーピングしたい

例えば

const list = [
  {
    "name": "taro",
    "role": "admin"
  },
  {
    "name": "jiro",
    "role": "staff"
  },
  {
    "name": "hanako",
    "role": "admin"
  }
];

ってデータが有った場合

{
  "admin": [
    {
      "name": "taro",
      "role": "admin"
    },
    {
      "name": "hanako",
      "role": "admin"
    }
  ],
  "staff": [
    {
      "name": "jiro",
      "role": "staff"
    }
  ]
}

ってやりたい

JavascriptにはgroupBy関数がない

Rubyなら[].group_byで一発なのに。。。ってことで自分で関数を作るしか無い。JavaScriptのサンプルコードは多いがTypeScriptになるとあんまりなかったのでメモ

コード

export const groupBy = <T, K extends keyof any>(arr: T[], key: (i: T) => K) =>
  arr.reduce((groups, item) => {
    (groups[key(item)] ||= []).push(item);
    return groups;
  }, {} as Record<K, T[]>);

// 例
const list = [
  {
    "name": "taro",
    "role": "admin"
  },
  {
    "name": "jiro",
    "role": "staff"
  },
  {
    "name": "hanako",
    "role": "admin"
  }
];
console.log(groupBy(list, (x) => x.role));

見ればわかるが、第一引数は対象の配列、第二引数は何でグルーピングしたいかをアロー関数で指定する。

ネイティブで対応されるかも。。。?

かも?って疑問符なのはまだ全然実装まで遠そうだから。

developer.mozilla.org

まさに欲しい機能!って思ったがChromeにすら実装されてないので道のりは長そうだ。。