JavaScriptで2つのオブジェクトを結合(ユニオン)する方法
JavaScriptでは、複数のオブジェクトの値をひとつにまとめたい場面がよくあります。例えば、次のようなオブジェクトがあったとします。
const obj1 = { name: " ", email: " " };
そして、もうひとつはこのようなオブジェクトです。
const obj2 = { name: ['x'], email: ['y']};
ここで必要になるのは、これら2つのオブジェクトを受け取り、各キーの値を配列としてまとめた「ユニオン(和集合)」を返す関数です。期待する出力は以下のイメージです。
const output = { name: [" ", ['x']], email: [" ", ['y']] };
実装例
for...in ループを使って、両方のオブジェクトの値を順番に新しいオブジェクトへ追加していく方法を見てみましょう。
const obj1 = { name: " ", email: " " };
const obj2 = { name: ['x'], email: ['y']};
const objectUnion = (obj1 = {}, obj2 = {}) => {
const obj3 = {};
// 1つ目のオブジェクトの値を配列に格納
for (let i in obj1) {
obj3[i] = [obj1[i]];
}
// 2つ目のオブジェクトの値を同じキーに追加
for (let i in obj2) {
if (obj3[i]) {
obj3[i].push(obj2[i]);
} else {
obj3[i] = [obj2[i]];
}
}
return obj3;
};
console.log(objectUnion(obj1, obj2));
出力結果
コンソールには次のように出力されます。
{ name: [ ' ', [ 'x' ] ], email: [ ' ', [ 'y' ] ] }
コードの解説
この関数の処理の流れは以下のとおりです。
- 第1段階: 最初の for...in ループで obj1 の各キーを走査し、その値を配列にラップして結果オブジェクトに設定します。
- 第2段階: 次のループで obj2 を走査し、同じキーがすでに存在すれば push() で値を追加し、存在しなければ新しく配列を作成します。
- 引数の初期値: デフォルトパラメータ({})を指定しているため、どちらか一方が undefined でもエラーにならず安全に動作します。
なお、キー名(name や email)をあらかじめ固定してしまうと汎用性が失われてしまいます。上記の例では、どんなキーを持つオブジェクトにも対応できるように改良しています。
補足:Object.assign やスプレッド構文との違い
単純にオブジェクトをマージしたいだけであれば、Object.assign() やスプレッド構文(...)が利用できます。ただしこれらの方法は、後ろのオブジェクトの値で前の値を上書きするため、今回のように「両方の値を保持した配列」を作りたいケースには適していません。
const merged = { ...obj1, ...obj2 };
// 結果:{ name: ['x'], email: ['y'] } ← 値が上書きされる
すべての値を残したい場合には、本記事で紹介したようなループ処理によるユニオンの実装が有効です。
-
JavaScriptで2つのオブジェクトをマージする方法を解説
JavaScriptでは、スプレッド構文(...)を使うことで、2つのオブジェクトを簡単に1つにマージ(結合)できます。各オブジェクトの前に「...」を付けて新しいオブジェクトリテラル内に展開するだけで、すべてのプロパティが統合されたオブジェクトが生成されます。以下に、2つのJavaScriptオブジェクトをマージするコードの例を示します。コード例<!DOCTYPE html> <html lang=ja> <head> <meta charset=UTF-8 /> <meta name=viewport content=width=dev
-
【図解付き】JavaScriptにおけるオブジェクトの等価性をわかりやすく解説
JavaScriptでは、文字列・数値・真偽値などのプリミティブ型はその「値」に基づいて比較されます。一方、オブジェクト(ネイティブオブジェクトでも独自に定義したカスタムオブジェクトでも)は「参照」に基づいて比較されます。 「参照による比較」とは、複数のオブジェクトがメモリ上の同じ場所を指しているかどうかを判定するという意味です。つまり、プロパティの中身が完全に一致していても、別々に生成された2つのオブジェクトは等しいとみなされません。 押さえておきたいポイント プリミティブ型: 値が同じであれば == や === の比較で true になる オブジェクト型: 同じインスタンス(同一の参照