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

JavaScriptでidをキーに2つのオブジェクト配列を結合する方法

はじめに

次のような、子(child)親(parent)の2つのJSONオブジェクト配列があったとします。

const child = [{
    id: 1,
    name: 'somename',
    parent: {
        id: 2
    },
},
{
    id: 2,
    name: 'some child name',
    parent: {
        id: 4
    }
}];
const parent = [{
    id: 1,
    parentName: 'The first',
    child: {}
},
{
    id: 2,
    parentName: 'The second',
    child: {}
},
{
    id: 3,
    parentName: 'The third',
    child: {}
},
{
    id: 4,
    parentName: 'The fourth',
    child: {}
}];

ここで必要となるのは、この2つの配列を引数として受け取るJavaScript関数です。

この関数は、child配列の各オブジェクトを、child.parent.idparent.idが一致する対応するparentオブジェクトへマージする役割を担います。

したがって、最終的な出力は次のようになります。

const output = [
    {
        id: 1,
        parentName: 'The first',
        child: {}
    },
    {
        id: 2,
        parentName: 'The second',
        child: {
            id: 1,
            name: 'somename'
        }
    },
    {
        id: 3,
        parentName: 'The third',
        child: {}
    },
    {
        id: 4,
        parentName: 'The fourth',
        child: {
            id: 2,
            name: 'some child name'
        }
    }
];

サンプルコード

この処理を実現する基本的なコードは次のとおりです。

const combineParentChild = (parent, child) => {
    const combined = [];
    for (let i = 0; i < parent.length; i++) {
        for (let j = 0; j < child.length; j++) {
            if (child[j].parent.id === parent[i].id) {
                parent[i].child.id = child[j].id;
                parent[i].child.name = child[j].name;
                break;
            }
        }
        combined.push(parent[i]);
    }
    return combined;
};
console.log(combineParentChild(parent, child));

このコードでは、外側のループで親オブジェクトを、内側のループで子オブジェクトを順に走査し、idが一致した時点で子の情報を親のchildプロパティに書き込んでいます。

出力結果

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

[
    { id: 1, parentName: 'The first', child: {} },
    {
        id: 2,
        parentName: 'The second',
        child: { id: 1, name: 'somename' }
    },
    { id: 3, parentName: 'The third', child: {} },
    {
        id: 4,
        parentName: 'The fourth',
        child: { id: 2, name: 'some child name' }
    }
]

より効率的な実装:Mapを活用する

上記の実装は二重ループを使用しているため、計算量がO(n×m)となり、データ件数が増えるとパフォーマンスが低下します。そこで、Mapを使って子オブジェクトを事前にインデックス化すると、計算量をO(n+m)まで抑えられます。

const combineParentChild = (parent, child) => {
    // 子オブジェクトを親のidをキーにしてMapに登録
    const childMap = new Map(
        child.map(c => [c.parent.id, { id: c.id, name: c.name }])
    );
    // 元の配列を変更せず、新しいオブジェクトを生成して返す
    return parent.map(p => ({
        ...p,
        child: childMap.get(p.id) || {}
    }));
};
console.log(combineParentChild(parent, child));

この実装では、スプレッド構文(...)を使って元の配列を破壊的に変更せずに済むため、副作用のない安全なコードになります。実務では、こちらのMapを使った方法がおすすめです。

まとめ

親子関係にある2つのオブジェクト配列を結合する場合は、idなどのキーを手がかりに対応付けを行います。小規模なデータであればシンプルな二重ループでも十分ですが、パフォーマンスと保守性を重視するなら、Mapを使った実装が効果的です。

  1. JavaScriptで2つの配列を結合する方法【concat()とスプレッド構文】

    JavaScriptで2つの配列を1つにまとめたい場合、最も一般的なのが concat() メソッドです。このメソッドは、元の配列を変更することなく、複数の配列や値を連結した新しい配列を返します。 concat()メソッドの基本構文 let 新しい配列 = 配列A.concat(配列B); サンプルコード 以下は、ボタンをクリックすると2つの配列を結合し、その結果を画面に表示する完全なサンプルです。 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8&

  2. JavaScriptで2つのオブジェクトをマージする方法を解説

    JavaScriptでは、スプレッド構文(...)を使うことで、2つのオブジェクトを簡単に1つにマージ(結合)できます。各オブジェクトの前に「...」を付けて新しいオブジェクトリテラル内に展開するだけで、すべてのプロパティが統合されたオブジェクトが生成されます。以下に、2つのJavaScriptオブジェクトをマージするコードの例を示します。コード例<!DOCTYPE html> <html lang=ja> <head> <meta charset=UTF-8 /> <meta name=viewport content=width=dev