JavaScript: 配列のコピーはconcat、slice、スプレッド構文のどれを使うべき?
JavaScriptで配列の項目を別の配列にコピーする方法
浅いコピー(シャローコピー)
浅いコピーは、元の配列とコピー先の配列が同じデータを参照する状態を作ります。つまり、どちらかの配列の項目を変更すると、もう一方の配列にも反映されます。
concat()
メソッドは、引数に配列を指定すると、その配列を連結した新しい配列を返します。
const originalArray = [1, 2, 3];
const copiedArray = originalArray.concat();
console.log(copiedArray); // [1, 2, 3]
copiedArray[0] = 4;
console.log(originalArray); // [4, 2, 3]
slice()
メソッドは、引数に指定した範囲の要素を持つ新しい配列を返します。
const originalArray = [1, 2, 3];
const copiedArray = originalArray.slice();
console.log(copiedArray); // [1, 2, 3]
copiedArray[0] = 4;
console.log(originalArray); // [1, 2, 3]
スプレッド構文は、配列の要素を展開して、カンマ区切りで記述することができます。
const originalArray = [1, 2, 3];
const copiedArray = [...originalArray];
console.log(copiedArray); // [1, 2, 3]
copiedArray[0] = 4;
console.log(originalArray); // [1, 2, 3]
map()
メソッドは、配列の各要素に対して関数を適用し、新しい配列を生成します。
const originalArray = [1, { name: "John" }, [1, 2, 3]];
const copiedArray = originalArray.map(item => JSON.parse(JSON.stringify(item)));
console.log(copiedArray); // [1, {"name":"John"}, [1, 2, 3]]
copiedArray[1].name = "Mary";
console.log(originalArray); // [1, { name: "John" }, [1, 2, 3]]
ライブラリの利用
lodash
などのライブラリには、配列の深いコピーを行うための関数を提供しています。
const _ = require("lodash");
const originalArray = [1, { name: "John" }, [1, 2, 3]];
const copiedArray = _.cloneDeep(originalArray);
console.log(copiedArray); // [1, {"name":"John"}, [1, 2, 3]]
copiedArray[1].name = "Mary";
console.log(originalArray); // [1, { name: "John" }, [1, 2, 3]]
JavaScriptで配列の項目を別の配列にコピーするには、浅いコピーと深いコピーの 2 種類の方法があります。それぞれの特徴を理解し、状況に応じて使い分けることが重要です。
浅いコピー(シャローコピー)
concat() メソッド
const originalArray = [1, 2, 3];
const copiedArray = originalArray.concat();
console.log(copiedArray); // [1, 2, 3]
copiedArray[0] = 4;
console.log(originalArray); // [4, 2, 3]
slice() メソッド
const originalArray = [1, 2, 3];
const copiedArray = originalArray.slice();
console.log(copiedArray); // [1, 2, 3]
copiedArray[0] = 4;
console.log(originalArray); // [1, 2, 3]
スプレッド構文
const originalArray = [1, 2, 3];
const copiedArray = [...originalArray];
console.log(copiedArray); // [1, 2, 3]
copiedArray[0] = 4;
console.log(originalArray); // [1, 2, 3]
深いコピー(ディープコピー)
map() メソッド
const originalArray = [1, { name: "John" }, [1, 2, 3]];
const copiedArray = originalArray.map(item => JSON.parse(JSON.stringify(item)));
console.log(copiedArray); // [1, {"name":"John"}, [1, 2, 3]]
copiedArray[1].name = "Mary";
console.log(originalArray); // [1, { name: "John" }, [1, 2, 3]]
ライブラリの利用
const _ = require("lodash");
const originalArray = [1, { name: "John" }, [1, 2, 3]];
const copiedArray = _.cloneDeep(originalArray);
console.log(copiedArray); // [1, {"name":"John"}, [1, 2, 3]]
copiedArray[1].name = "Mary";
console.log(originalArray); // [1, { name: "John" }, [1, 2, 3]]
補足
- 上記のサンプルコードは、基本的な使い方を示すものです。実際のコードでは、必要に応じて処理をカスタマイズする必要があります。
- 配列の要素が複雑なオブジェクトの場合、深いコピーの方が安全です。
- 浅いコピーと深いコピーのどちらを使用するかは、パフォーマンスとメモリ使用量のトレードオフにも影響されます。
配列の項目を別の配列にコピーする他の方法
for
ループを使用して、元の配列の各要素をコピー先の配列に1つずつ追加することができます。
const originalArray = [1, 2, 3];
const copiedArray = [];
for (let i = 0; i < originalArray.length; i++) {
copiedArray.push(originalArray[i]);
}
console.log(copiedArray); // [1, 2, 3]
reduce()
メソッドを使用して、元の配列を1つの値に集約し、それをコピー先の配列に代入することができます。
const originalArray = [1, 2, 3];
const copiedArray = originalArray.reduce((acc, item) => {
acc.push(item);
return acc;
}, []);
console.log(copiedArray); // [1, 2, 3]
スプレッド構文と Object.assign()
メソッドを使用して、元の配列を新しい配列にコピーすることができます。
const originalArray = [1, 2, 3];
const copiedArray = [...Object.assign({}, originalArray)];
console.log(copiedArray); // [1, 2, 3]
- 処理速度が重要な場合は、
for
ループを使用するのが最も効率的です。 - コードの簡潔さを重視する場合は、スプレッド構文を使用するのがおすすめです。
- 配列の要素が複雑なオブジェクトの場合は、深いコピーを行うために
map()
メソッドやライブラリを使用する必要があります。
javascript arrays