JavaScript標準でgroupBy関数が実装されています。2023年11月現在Safari以外の主要なブラウザで実装済みで、SafariもTechnology Previewのようです。
(現在MDNの日本語の記事は古い情報のままになっており、現行と異なるので注意! →更新していただきました。ありがとうございます!)
Proposal の Stage はすでに 4 / Finished なので規格として確定済みです。
基本的な使い方
よくあるgroupByです。配列(Iterable)とキーを抽出する関数の二つを指定すると、キーで配列をグループ化します。
const ret = Object.groupBy([
{ name: '山田太郎', address: '東京' },
{ name: '山田次郎', address: '愛知' },
{ name: '山田三郎', address: '大阪' },
{ name: '山田四郎', address: '東京' },
], x => x.address);
// ret = {
// "東京": [
// { "name": "山田太郎", "address": "東京" },
// { "name": "山田四郎", "address": "東京" }
// ],
// "愛知": [
// { "name": "山田次郎", "address": "愛知" }
// ],
// "大阪": [
// { "name": "山田三郎", "address": "大阪" }
// ]
// }
2つある
JavaScriptのgroupByは2つあります。Object.groupBy()
と Map.groupBy()
です。Object.groupBy()
はプレーンなオブジェクトで返し、Map.groupBy()
は Map
型で返します。
プレーンなオブジェクトのキー(プロパティ)になれるのは文字列だけなので、文字列以外をキーにしたい場合は Map.groupBy()
を使うという事です。
Map.groupBy([{ hoge: 3 }, { hoge: 4 }, { hoge: 3 }], x => x.hoge);
配列のメソッドではない
groupByは配列のメソッドになるのが直感的と思いますが、Object
と Map
の静的メソッドになっています。これはライブラリの中には配列のプロトタイプを書き換えてgroupByを挿入するものがあるのでそれの互換性を崩さないようにした結果のようです。
正直 Array
に入れた方が自然でよい気がしますがね。今後もこういうみんなほしいと思っているメソッドは全部不自然な形でしか標準には入れられないという事になっちゃうのかな…そこは残念。