配列をキーごとにまとめる(グループ化)

Object.groupBy が使えるならそれが最短です。使えない環境向けの reduce での書き方、キーが数値や undefined になる罠、件数だけ数える形までまとめます。

実行して検証済み処理系Node 22.22.3対応ES2024難易度●●○○○目安8更新

答え

Object.groupBy() に「何をキーにするか」を渡します。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
{ A: [ { name: 'あかり', team: 'A' }, { name: 'はると', team: 'A' } ], B: [ { name: 'ゆうと', team: 'B' } ] }
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
{ '0': [ 3, 6 ], '1': [ 1, 4 ], '2': [ 2, 5 ] } [ '0', '1', '2' ]

ES2024 です。(Node 21 / Chrome 117 / Safari 17.4 以降) 古い環境も相手にするなら、後述の reduce() で書きます。

上のコードは書き換えて実行できます。u.teamu.name.length にしてみてください。

キーは必ず文字列になる

Object.groupBy() の戻り値はオブジェクトなので、キーは文字列に変換されます

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
Map(3) { 1 => [ 1, 4 ], 2 => [ 2, 5 ], 0 => [ 3, 6 ] } [ 3, 6 ] undefined
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ 'A', 'B' ] [ 'あかり', 'はると' ]

数値でキーを引きたいときは Map.groupBy() を使います。キーの型が保たれます。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
2
javascript
const users = [
{ name: 'あかり', team: 'A' },
{ name: 'ゆうと' },
];

const byTeam = Object.groupBy(users, u => u.team);

console.log(Object.keys(byTeam));
console.log(byTeam.undefined.length);
[ 'A', 'undefined' ] 1

Object.groupBy() なら '0'Map.groupBy() なら 0 で引きます。 取り違えると undefined になります。

戻り値 キーの型 順序
Object.groupBy() オブジェクト 文字列になる 数字に見えるキーが先
Map.groupBy() Map そのまま 出てきた順

オブジェクトをキーにしたいなら Map.groupBy() しかありません。

古い環境で書く

reduce() で同じことができます。中身は「無ければ配列を作って、押し込む」だけです。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ 'A', '未所属' ] [ 'A' ]
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
{ 'りんご': 3, 'みかん': 1, 'ぶどう': 1 }

??= は「まだ無ければ入れる」です。書けない環境なら、こう書きます。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
{ 'りんご': 2, 'みかん': 1 }
example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
{ '東京': 1500, '大阪': 800 }

{ ...acc } で作り直さないでください。 要素の数だけ複製することになります。 理由は Array.prototype.reduce() にあります。

キーが undefined になる

キーを取り出す式が空振りすると、undefined という名前のグループができます。

example.js
出力書き換えて実行できます
Ctrl+Enter でも実行JS · UTF-8
[ '2026-9', '2026-8' ] [ 1, 2 ]

文字列の 'undefined' です。 気づかずに集計に混ざります。

既定値を決めるか、先に弾いてください。

「所属が無い人」を見せたいのか、捨てたいのかを決めてから書きます。

件数だけ数える

グループの中身が要らないなら、配列を作らず数えるほうが安いです。

groupBy で作ってから数えることもできます。読みやすいほうを選んでください。

グループごとに合計する

グループ化してから、各グループを reduce() します。

合計の落とし穴(小数・空配列・文字列が混ざる)は 配列の合計を出す にまとめてあります。

複数のキーでまとめる

キーを繋いだ文字列にします。区切りには、値に出てこない文字を選んでください。

'2026-9' が先に来ています。数字だけのキーなら小さい順に並びますが、'2026-9' は数字ではないので出てきた順です。ここでも順序に頼らないでください。

キーに使う値そのものに区切り文字が入りうるなら、この方法は使えません('a-b' と 'a' + '-b' が衝突します)。そのときは Map.groupBy と入れ子にしてください。

この記事の根拠

  1. Object.groupBy — ECMAScript® 2026 Language Specificationtc39.es
  2. Map.groupBy — ECMAScript® 2026 Language Specificationtc39.es
  3. Object.groupBy() — MDNdeveloper.mozilla.org

掲載しているコード例は、公開前に読み手が押したときに動くのと同じもので実行して出力を突き合わせています。結果はリポジトリに残しています。

このページの原文(Markdown)