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

JavaScriptで2つのオブジェクト配列を重複なくマージする方法

はじめに

JavaScriptで開発をしていると、2つのオブジェクト配列を1つにまとめたい場面はよくあります。しかし、単純に連結するだけでは同じプロパティ値を持つオブジェクトが重複してしまうという問題が発生します。

本記事では、「name」プロパティを一意の識別キーとして使い、重複オブジェクトを除外しながら2つの配列をマージする方法を解説します。


前提となるデータ

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

const arr1 = [
    {name:'test', lastname: 'test', gender:'f'},
    {name:'test1', lastname: 'test1', gender:'f'},
    {name:'test2', lastname: 'test2', gender:'m'}
];
const arr2 = [
    {name:'test21', lastname: 'test21', gender:'f'},
    {name:'test1', lastname: 'test1', gender:'f'},
    {name:'test2', lastname: 'test2', gender:'m'},
    {name:'test22', lastname: 'test22', gender:'m'}
];

各配列の内部には重複したオブジェクトは存在しません(「name」プロパティの値で判定)。しかし、arr1 と arr2 の間ではtest1test2 のように同じ名前を持つオブジェクトが重複しています。

要件

ここで求められているのは、次のような処理を行うJavaScript関数です。

  • 2つの配列を引数として受け取る
  • 両方の配列に含まれるすべての一意なオブジェクトだけを格納した新しい配列を返す
  • オブジェクトの一意性は「name」プロパティの値で判定する

実装コード

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

const arr1 = [
    {name:'test', lastname: 'test', gender:'f'},
    {name:'test1', lastname: 'test1', gender:'f'},
    {name:'test2', lastname: 'test2', gender:'m'}
];
const arr2 = [
    {name:'test21', lastname: 'test21', gender:'f'},
    {name:'test1', lastname: 'test1', gender:'f'},
    {name:'test2', lastname: 'test2', gender:'m'},
    {name:'test22', lastname: 'test22', gender:'m'}
];
const mergeUniquely = (arr1 = [], arr2 = []) => {
    const newArr = arr1.concat(arr2);
    const map = {};
    const res = [];
    newArr.forEach(el => {
        if(!map[el['name']]){
            res.push(el);
            map[el['name']] = 1;
        };
    });
    return res;
};
console.log(mergeUniquely(arr1, arr2));

コードのポイント

  • arr1.concat(arr2) でまず2つの配列を連結します。
  • 連結した配列を forEach でループし、既出の「name」かどうかをオブジェクト map で判定します。
  • 未登録の場合のみ結果配列 res に追加し、map に記録することで重複を効率よく除外しています。

この方法なら、要素数が多くても線形時間(O(n))で処理できるため、パフォーマンス面でも優れています。

実行結果

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

[
    { name: 'test', lastname: 'test', gender: 'f' },
    { name: 'test1', lastname: 'test1', gender: 'f' },
    { name: 'test2', lastname: 'test2', gender: 'm' },
    { name: 'test21', lastname: 'test21', gender: 'f' },
    { name: 'test22', lastname: 'test22', gender: 'm' }
]

ご覧の通り、重複していた test1test2 のオブジェクトはそれぞれ1つだけ残り、両配列の一意なデータが正しく統合されています。

まとめ

オブジェクト配列のマージ時に重複を排除したい場合は、連結 → 一意キーによる判定 → 結果配列への追加という流れが基本です。判定キーとなるプロパティを変えれば、name 以外の項目でも同じ考え方を応用できます。また、ES2019以降の環境であれば、Map オブジェクトや Array.prototype.reduce() を使って同様の処理をより簡潔に書くことも可能です。用途に合わせて最適な方法を選択してください。

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

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

  2. 【JavaScript入門】複数のオブジェクトを1つにマージして単一のオブジェクト配列を作成する方法

    JavaScriptでは、Object.assign()メソッドとスプレッド構文(...)を組み合わせることで、配列内の複数のオブジェクトを1つのオブジェクトに簡単にマージすることができます。 Object.assign()は、1つ以上のコピー元オブジェクトから、コピー先のオブジェクトへすべてのプロパティをコピーするためのメソッドです。スプレッド構文を使って配列の要素を展開することで、各オブジェクトのキーと値が1つのオブジェクトに統合されます。 コード例 以下のコードは、配列内の複数のオブジェクトを単一のオブジェクトにマージする例です。 <!DOCTYPE html> <ht