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

JavaScriptでキーごとにサイズの異なる2つのオブジェクト配列をマージする方法

JavaScriptでは、共通するキー(idなど)を基準にして、要素数が異なる複数のオブジェクト配列を1つの配列に統合したいケースがよくあります。本記事では、そのようなマージ処理を実現する方法を具体的なコード例とともに解説します。

問題の定義

まず、次のようなオブジェクトがあると仮定します。

const obj = {
    "part1": [{"id": 1, "a": 50},{"id": 2, "a": 55},{"id": 4, "a": 100}],
    "part2":[{"id": 1, "b": 40}, {"id": 3, "b": 45}, {"id": 4, "b": 110}]
};

このオブジェクトには part1part2 の2つの配列が含まれており、それぞれ異なるプロパティ(a と b)を持っています。両配列に共通するのは id プロパティだけです。

求められているのは、この2つの配列を id をキーとして結合し、以下のような出力を生成する関数を作成することです。

const output = [
    {"id": 1, "a": 50, "b": 40},
    {"id": 2, "a": 55},
    {"id": 3, "b": 45},
    {"id": 4, "a": 100, "b": 110}
];

ポイントは以下の3点です。

  • 同じ id を持つ要素は、両方のプロパティ(a と b)をまとめて1つのオブジェクトにする
  • 片方にしか存在しない id は、持っているプロパティのみで構成される
  • 最終的な結果は id の昇順にソートする

実装コード

この要件を満たすコードは以下のとおりです。

const obj = {
    "part1": [{"id": 1, "a": 50},{"id": 2, "a": 55},{"id": 4, "a": 100}],
    "part2":[{"id": 1, "b": 40}, {"id": 3, "b": 45}, {"id": 4, "b": 110}]
};
const mergeObject = (obj = {}) => {
    let result = [];
    result = Object.keys(obj).reduce(function (hash) {
        return function (r, k) {
            obj[k].forEach(function (o) {
                if (!hash[o.id]) {
                    hash[o.id] = {};
                    r.push(hash[o.id]);
                }
                Object.keys(o).forEach(function (l) {
                    hash[o.id][l] = o[l];
                });
            });
            return r;
        };
    }(Object.create(null)), []).sort((a, b) => {
        return a['id'] − b['id'];
    });
    return result;
};
console.log(mergeObject(obj));

コードの仕組み

この実装の動作を簡単に整理してみましょう。

  1. ハッシュマップの用意: Object.create(null) によってプロトタイプを持たない空のオブジェクトを作成し、id をキーとした検索テーブル(ハッシュ)として利用します。これにより重複チェックを高速に行えます。
  2. reduceによる走査: Object.keys(obj) で各配列(part1、part2)を取り出し、reduce を使ってすべての要素を順番に処理していきます。
  3. 既存idの判定: 各要素の id がハッシュに存在しない場合は新しいオブジェクトを作成して結果配列に追加し、存在する場合は既存のオブジェクトに対してプロパティを上書き・追記します。この仕組みにより、両配列に存在する id のプロパティが自然に統合されます。
  4. ソート処理: 最後に sort() を使って、結果を id の昇順に並べ替えています。

実行結果

コンソールには次のように出力されます。

[
    { id: 1, a: 50, b: 40 },
    { id: 2, a: 55 },
    { id: 3, b: 45 },
    { id: 4, a: 100, b: 110 }
]

期待どおり、id: 1id: 4 は両方のプロパティを持つオブジェクトに統合され、それ以外の要素は元のプロパティのみを保持したまま1つの配列にまとめられました。

まとめ

要素数やプロパティ構成が異なる複数のオブジェクト配列をマージする場合は、「idをキーにしたハッシュマップで一意性を管理しながらプロパティを集約する」というアプローチが有効です。今回紹介した reduce + ハッシュマップの手法は、配列が3つ以上に増えても Object.keys(obj) が自動的に対応してくれるため、拡張性にも優れています。

  1. JavaScriptで2つの配列を乗算する方法|forループとmap()の実装例

    JavaScriptで2つの配列の各要素同士を乗算し、その結果を新しい配列として取得する方法を解説します。基本的にはforループでインデックスを順番に処理しながら、対応する位置にある要素同士を掛け合わせていくシンプルなアプローチです。 2つの配列を乗算するサンプルコード 以下の例では、「CLICK HERE」ボタンをクリックすると、配列 arr と arr1 の対応する要素が乗算され、結果が新しい配列 multArray に格納された上で画面に表示されます。 <!DOCTYPE html> <html lang=en> <head> <meta ch

  2. 【JavaScript】2つの配列を1つのオブジェクトに変換する方法をわかりやすく解説

    2つの配列を1つのJavaScriptオブジェクトに変換できる? はい、可能です。JavaScriptでは「キー」となる配列と「値」となる配列の2つを組み合わせて、1つのオブジェクトを作成できます。最も基本的な方法は、forEach()メソッドで片方の配列をループ処理しながら、もう片方の配列の対応する要素を値として代入していくやり方です。 以下に、実際に動作するサンプルコードを紹介します。 コード例 <!DOCTYPE html> <html lang=ja> <head> <meta charset=UTF-8 /> <meta name