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

JavaScriptで配列の要素をuuidなどのプロパティ値ごとにグループ化する方法

はじめに

JavaScript開発では、オブジェクトの配列を特定のプロパティの値をもとにグループ化したい場面がよくあります。例えば、uuidが同じオブジェクト同士をひとつの配列にまとめ、結果を二次元配列として取得したいケースなどです。

例として、次のようなオブジェクトの配列があるとします。

const arr = [
  {"name": "toto", "uuid": 1111},
  {"name": "tata", "uuid": 2222},
  {"name": "titi", "uuid": 1111}
];

ここで求められているのは、uuidプロパティの値が同じオブジェクト同士を、それぞれ独立した配列に分割する関数を書くことです。

期待される出力

上記の配列に対して処理を行うと、結果は次のようになります。

const output = [
  [
    {"name": "toto", "uuid": 1111},
    {"name": "titi", "uuid": 1111}
  ],
  [
    {"name": "tata", "uuid": 2222}
  ]
];

uuidが「1111」の2つのオブジェクトがひとつの配列に、「2222」のオブジェクトが別の配列にきちんとまとめられていますね。

実装コード

この処理は、ハッシュマップ(連想配列)を使うことで効率的に実装できます。以下がそのコードです。

const arr = [
  {"name": "toto", "uuid": 1111},
  {"name": "tata", "uuid": 2222},
  {"name": "titi", "uuid": 1111}
];

const groupByElement = arr => {
  const hash = Object.create(null),
        result = [];

  arr.forEach(el => {
    if (!hash[el.uuid]) {
      hash[el.uuid] = [];
      result.push(hash[el.uuid]);
    }
    hash[el.uuid].push(el);
  });

  return result;
};

console.log(groupByElement(arr));

コードの解説

  • Object.create(null): プロトタイプを持たない空のオブジェクトを作成します。これにより、toStringconstructorといった組み込みプロパティ名との衝突を防げます。
  • hashuuidの値をキーとして、対応する配列への参照を保持します。
  • result: グループ化された配列を順番に格納する最終的な出力用配列です。
  • forEach: 各要素について、そのuuidのグループがまだ存在しなければ新しい配列を作成し、resultに登録したうえで要素を追加します。

重要なポイントは、resultには配列そのものではなく参照をpushしている点です。そのため、その後のhash[el.uuid].push(el)で要素を追加すると、result内の配列にも自動的に反映されます。

コンソール出力

実際にコードを実行すると、コンソールには次のように表示されます。

[
  [ { name: 'toto', uuid: 1111 }, { name: 'titi', uuid: 1111 } ],
  [ { name: 'tata', uuid: 2222 } ]
]

補足: Mapを使ったより汎用的な書き方

同じ処理は、ES6のMapを使うことでより安全かつ柔軟に実現できます。

const groupByElement = arr => {
  const map = new Map();

  for (const el of arr) {
    if (!map.has(el.uuid)) {
      map.set(el.uuid, []);
    }
    map.get(el.uuid).push(el);
  }

  return [...map.values()];
};

Mapは任意の型の値をキーとして扱えるため、数値・文字列・シンボルなど、どんなプロパティでグループ化する場合でも安心して利用できます。

まとめ

オブジェクトの配列を特定のプロパティでグループ化する際は、ハッシュテーブル(Mapやプレーンなオブジェクト)を中間データとして使うのが定番のアプローチです。この手法なら計算量はO(n)で済み、大量のデータでも高速に処理できます。ぜひ自分のプロジェクトでも活用してみてください。

  1. JavaScriptでIDごとにオブジェクトの配列をグループ化する方法

    JavaScriptでオブジェクトの配列をidなどの特定のキーごとにグループ化したい場合、reduce()メソッドを使うと簡潔に実装できます。この記事では、どのプロパティにも対応できる汎用的なgroupBy関数を作成し、実際のサンプルコードとともにその仕組みを詳しく解説します。 reduce()によるグループ化の考え方 reduce()は、配列の各要素を順番に処理しながら、1つの累積値(ここではオブジェクト)を組み立てていくメソッドです。各要素からキーの値を取り出し、その値がまだ結果オブジェクトに存在しなければ新しい配列を作成して、そこへ要素を追加していくことでグループ化を実現します。 サ

  2. JavaScriptで配列の最後の要素を取得・表示する方法

    配列の最後の要素を取得して画面に表示するには、pop()メソッドを利用するのが手軽です。以下に、ボタンをクリックすると配列の最後の要素を表示するサンプルコードを示します。 コード例 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> &