JavaScript
 Computer >> コンピューター >  >> プログラミング >> JavaScript

【JavaScript】オブジェクトの配列を任意のキーでグループ化する方法

JavaScriptでデータを扱っていると、オブジェクトの配列を特定のプロパティ(キー)を基準にグループ化したい場面は非常によくあります。例えば、車の情報が入った配列を「メーカー」ごとにまとめたい場合などです。

本記事では、reduce()メソッドを使った基本的な実装方法を中心に、実際のコード例とともにわかりやすく解説します。あわせて、より新しいObject.groupBy()を使ったモダンな書き方についても紹介します。

元データの例

まず、以下のような複数の車の情報を持つオブジェクトの配列を想定します。

const arr = [
  { make: 'audi', model: 'r8',      year: '2012' },
  { make: 'audi', model: 'rs5',     year: '2013' },
  { make: 'ford', model: 'mustang', year: '2012' },
  { make: 'ford', model: 'fusion',  year: '2015' },
  { make: 'kia',  model: 'optima',  year: '2012' },
];

期待される出力

この配列に対して、「make(メーカー)」プロパティをキーとしてグループ化を行うと、次のようなオブジェクトが得られます。同じmakeの値を持つ要素が、同じ配列の中にまとめられるイメージです。

const output = {
  audi: [
    { model: 'r8',  year: '2012' },
    { model: 'rs5', year: '2013' }
  ],
  ford: [
    { model: 'mustang', year: '2012' },
    { model: 'fusion',  year: '2015' }
  ],
  kia: [
    { model: 'optima', year: '2012' }
  ]
};

reduce()を使ったグループ化の実装

それでは、実際にグループ化を行う関数を実装してみましょう。ここでは配列のreduce()メソッドを活用します。

const arr = [
  { make: 'audi', model: 'r8',      year: '2012' },
  { make: 'audi', model: 'rs5',     year: '2013' },
  { make: 'ford', model: 'mustang', year: '2012' },
  { make: 'ford', model: 'fusion',  year: '2015' },
  { make: 'kia',  model: 'optima',  year: '2012' },
];

const groupByMake = (arr = []) => {
  let result = [];
  result = arr.reduce((r, a) => {
    r[a.make] = r[a.make] || [];
    r[a.make].push(a);
    return r;
  }, Object.create(null));
  return result;
};

console.log(groupByMake(arr));

コードのポイント解説

  • 初期値として空のオブジェクトを渡す:reduce()の第2引数にObject.create(null)を指定することで、プロトタイプを持たないプレーンなオブジェクトをアキュムレータとして使用しています。これにより、toStringなどObject.prototypeのプロパティ名との衝突を避けられます(通常の{}でも動作します)。
  • キーの存在チェック:r[a.make] = r[a.make] || [];の行では、該当するキーがまだ存在しない場合に空の配列で初期化しています。このイディオムにより、初登場のキーにも安全に対応できます。
  • 要素の追加:r[a.make].push(a);で現在処理中のオブジェクトを、対応するメーカーの配列に追加していきます。

実行結果(コンソール出力)

上記のコードを実行すると、コンソールには次のような結果が出力されます。各メーカー名がプロパティ名となり、その値として該当する車のオブジェクトが配列で格納されていることが確認できます。

{
  audi: [
    { make: 'audi', model: 'r8',      year: '2012' },
    { make: 'audi', model: 'rs5',     year: '2013' }
  ],
  ford: [
    { make: 'ford', model: 'mustang', year: '2012' },
    { make: 'ford', model: 'fusion',  year: '2015' }
  ],
  kia: [
    { make: 'kia', model: 'optima', year: '2012' }
  ]
}

補足:Object.groupBy()を使ったモダンな方法

ES2024で標準化されたObject.groupBy()を使うと、同様の処理を1行で記述できます。対応ブラウザやNode.jsのバージョンが新しい環境であれば、こちらの方法が最もシンプルです。

const grouped = Object.groupBy(arr, item => item.make);
console.log(grouped);

第1引数にグループ化対象の配列、第2引数にキーを決定するコールバック関数を渡すだけなので、独自のロジックを書く必要がありません。ただし、古いランタイムでは利用できないため、その場合は前述のreduce()を使った実装が有効です。

まとめ

オブジェクトの配列をキーでグループ化する場合、reduce()を使えばどの環境でも確実に実装できます。「キーがなければ初期化し、あれば追加する」という流れさえ押さえておけば、任意のプロパティに応用可能です。また、実行環境が新しければObject.groupBy()を使うことで、より簡潔に記述できることも覚えておくと便利でしょう。

  1. JavaScriptでオブジェクトを含む「配列の配列」をループ処理する方法

    JavaScriptでオブジェクトを含む多次元配列をループするには?JavaScriptでは、オブジェクトを含む配列の配列(入れ子構造の配列)をループ処理する際、forEach()メソッドをネストして使用し、さらにfor...inループで各オブジェクトのプロパティにアクセスするのが一般的な方法です。以下に、具体的な実装例を紹介します。コード例<!DOCTYPE html> <html lang=ja> <head> <meta charset=UTF-8 /> <meta name=viewport content=width=device

  2. JavaScriptで値に基づいてオブジェクトをグループ化する方法

    JavaScriptでは、reduce()メソッドを活用することで、配列内のオブジェクトを特定の値(プロパティ)に基づいて効率的にグループ化できます。たとえば、複数人のデータを「年齢」ごとにまとめたい場合などに役立ちます。ここでは、実際に動作するサンプルコードをもとに、実装手順と仕組みをわかりやすく解説します。 サンプルコード <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewpo