1. ホーム
  2. javascript

javascriptでオブジェクトの配列を別の配列にコピーする [重複]。

2023-09-22 09:38:38

質問

配列の各要素(要素はオブジェクト)を別の配列にコピーして、完全に独立させるにはどうしたらよいでしょうか。一方の配列の要素を変更しても、もう一方の配列に影響しないようにしたいのです。

どのように解決するのですか?

ここで重要なことは

  1. 配列のエントリはオブジェクトであり
  2. 一方の配列にあるオブジェクトへの変更がもう一方の配列に表示されないようにする。

つまり、単にオブジェクトを新しい配列(またはターゲット配列)にコピーするだけでなく コピー を作成する必要があります。

コピー先の配列がまだ存在しない場合...

...使用する map を使って新しい配列を作成し、オブジェクトをコピーしていきます。

const newArray = sourceArray.map(obj => /*...create and return copy of `obj`...*/);

...コピー操作は、オブジェクトをコピーする方法であれば何でもよく、使用ケースに応じてプロジェクトごとに大きく異なります。このトピックは、以下の回答で詳しく説明されています。 この質問 . しかし、例えば、オブジェクトだけをコピーして、そのプロパティが参照するオブジェクトはコピーしない場合は、スプレッド記法(ES2015+)を使用することができます。

const newArray = sourceArray.map(obj => ({...obj}));

これは各オブジェクトの(そして配列の)浅いコピーを行います。繰り返しになりますが、深いコピーについては、上記のリンク先の質問に対する回答を参照してください。

エッジケースを処理しようとしない、深いコピーのナイーブなフォームを使用した例です。エッジケースについては、そのリンク先の質問を参照してください。

function naiveDeepCopy(obj) {
    const newObj = {};
    for (const key of Object.getOwnPropertyNames(obj)) {
        const value = obj[key];
        if (value && typeof value === "object") {
            newObj[key] = {...value};
        } else {
            newObj[key] = value;
        }
    }
    return newObj;
}
const sourceArray = [
    {
        name: "joe",
        address: {
            line1: "1 Manor Road",
            line2: "Somewhere",
            city: "St Louis",
            state: "Missouri",
            country: "USA",
        },
    },
    {
        name: "mohammed",
        address: {
            line1: "1 Kings Road",
            city: "London",
            country: "UK",
        },
    },
    {
        name: "shu-yo",
    },
];
const newArray = sourceArray.map(naiveDeepCopy);
// Modify the first one and its sub-object
newArray[0].name = newArray[0].name.toLocaleUpperCase();
newArray[0].address.country = "United States of America";
console.log("Original:", sourceArray);
console.log("Copy:", newArray);
.as-console-wrapper {
    max-height: 100% !important;
}

宛先配列が存在する場合...

...そして、ソース配列の内容をそこに追加したい場合は push とループさせます。

for (const obj of sourceArray) {
    destinationArray.push(copy(obj));
}

特に理由がなくても、人はどうしても "ワンライナー "を欲することがあります。そのような場合は、新しい配列を作成し、それを展開するためにスプレッド記法を使用して、1つの push を呼び出すことができます。

destinationArray.push(...sourceArray.map(obj => copy(obj)));