JavaScriptで
配列をコピーするためには、
さまざまな方法があります。
本記事では、
一般的な方法をいくつか紹介し、ご説明します!
Array.prototype.concat()メソッドを使う方法
concat()
メソッドは、
複数の配列や値を結合して
新しい配列を作成するためのメソッドです。
※公式(Mozilla)
元の配列を変更せず、
コピーしたい配列と結合して新しい配列を生成します。
例えば、
次のようにconcat()
を使って
配列をコピーすることができます。
let arr = [10, 20, 30, 40, 50];
let newArr = [].concat(arr);
console.log(newArr); // [10, 20, 30, 40, 50]
const array1 = ['a', 'b', 'c'];
const array2 = array1.concat();
console.log(array2); // Array ["a", "b", "c"]
1つ目のコードでは、
空の配列[]
に対してconcat()
メソッドを使い、
元の配列arr
を新しい配列newArr
にコピーしています。
これにより、元の配列を変更せずに複製が作成されます。
2つ目のコードでは、
array1.concat()に引数を何も渡さず、
同じ内容の新しい配列を複製し、
array2に代入しています。
特徴
concat()
は元の配列を変更しません。- 配列や単一の値を追加して
新しい配列を作ることができます。 - 元の配列の参照ではなく、
新しい配列が生成されるため、
浅いコピーが作成されます。
引数に別の配列を指定、結合することで、
新しい配列を作成することもできます。
let arr1 = [10, 20, 30];
let arr2 = [40, 50];
let combinedArr = arr1.concat(arr2);
console.log(combinedArr); // [10, 20, 30, 40, 50]
Array.prototype.slice()メソッドを使う方法
slice()
メソッドは、
指定した範囲内の要素を含む新しい配列を作成するメソッドです。
このメソッドは元の配列を変更せずに部分的なコピーを行います。
※公式(Mozilla)
let arr = [10, 20, 30, 40, 50];
let newArr = arr.slice(1, 4);
console.log(newArr); // [20, 30, 40]
この例では、
インデックス1から3までの要素が新しい配列にコピーされます。
特徴
- 部分的なコピー
配列の一部を範囲指定してコピーできます。 - 元の配列を変更しない
slice()
は新しい配列を返すため、
元の配列には影響を与えません。 - 簡単に部分的なデータを抽出
配列の一部だけを簡単に抽出できるため、
特定のデータ操作に便利です。
Array.from()
メソッド
Array.from()
は、
配列風オブジェクトや反復可能なオブジェクトから
新しい配列を作成するためのメソッドです。
元の配列の一部をコピーする場合にも使うことができます。
※公式(Mozilla)
let arr = [10, 20, 30, 40, 50];
let newArr = Array.from(arr.slice(2));
console.log(newArr); // [30, 40, 50]
slice()
と組み合わせて使用することで、
より柔軟に部分的なコピーが可能です。
特徴
- 配列風オブジェクトを変換
配列風オブジェクト(例: NodeList)や
文字列を配列に変換できます。 - 元の配列を変更しない
Array.from()
も新しい配列を返すため、
元のデータに影響を与えません。 - マッピング可能
Array.from()
はマップ関数を
引数に受け取ることができ、
変換しながら新しい配列を作成できます。
スプレッド演算子 (...
) を使った配列コピーの例
スプレッド演算子を使用すると、
簡単に配列のコピーを作成できます。
しかし、浅いコピーであるため、
ネストされた配列やオブジェクトの要素はコピーされず、
元の配列と新しい配列が同じネストされた要素を参照する点に注意が必要です。
基本的なスプレッド演算子でのコピー
let originalArray = [10, 20, 30];
let copiedArray = [...originalArray];
console.log(copiedArray); // [10, 20, 30]
この例では、originalArray
の内容をcopiedArray
にコピーしています。
元の配列と新しい配列は異なる参照を持っており、
それぞれ独立しています。
スプレッド演算子を使った浅いコピーとその例外
let originalArray = [10, 20, [30, 40]];
let copiedArray = [...originalArray];
// ネストされた配列の一部を変更
copiedArray[0] = 99;
console.log(originalArray); // [10, 20, [99, 40]]
console.log(copiedArray); // [10, 20, [99, 40]]
この例では、originalArray
の中にネストされた配列 [30, 40]
があります。
スプレッド演算子を使って originalArray
をコピーしましたが、
ネストされた配列は参照渡しとなっているため、copiedArray
の中のネストされた配列を変更すると、
元の originalArray
にも影響を与えてしまいます。
ネストされた配列を完全にコピーする方法(ディープコピー)
もし、ネストされた配列や
オブジェクトも独立してコピーしたい場合は、
ディープコピーを行う必要があります。
スプレッド演算子ではディープコピーができないため、
例えば、JSON.parse(JSON.stringify())
を使って
ディープコピーを行います。
let originalArray = [10, 20, [30, 40]];
let copiedArray = JSON.parse(JSON.stringify(originalArray));
// ネストされた配列の一部を変更
copiedArray[0] = 99;
console.log(originalArray); // [10, 20, [30, 40]]
console.log(copiedArray); // [10, 20, [99, 40]]
この例では、JSON.parse(JSON.stringify())
を使って
ディープコピーを実行しているため、copiedArray
の変更がoriginalArray
に影響を与えません。
スプレッド演算子の使いどころ
- 浅いコピーが問題ない場合
スプレッド演算子はシンプルで効率的な方法です。
配列やオブジェクトが浅い構造で、
ネストされた要素がない場合や、
ネストされた要素が変更されない場合に使うのが適しています。 - ディープコピーが必要な場合
配列やオブジェクトのネストされた部分も
完全に独立させたい場合は、
スプレッド演算子ではなく、
他のディープコピー手法
(JSON.parse(JSON.stringify())
やlodash
のcloneDeep()
など)を
使う必要があります。
自前:for
ループやforEach()
メソッド
for
ループやforEach()
メソッドを使って
手動で配列の一部をコピーする方法もあります。
この方法では、より細かい制御が可能です。
let arr = [10, 20, 30, 40, 50];
let newArr = [];
arr.forEach((item, index) => {
if (index > 1) newArr.push(item);
});
console.log(newArr); // [30, 40, 50]
特徴
- 柔軟性が高い
条件やロジックを組み合わせて、
細かい制御が可能です。 - 低レベルな操作
JavaScriptの基本的な構文を使うため、
配列操作の仕組みを理解しやすい。 - 効率は低い可能性がある
forEach()
やfor
ループを手動で使うと、
特定の操作で最適化がされない場合があります。
どのメソッドを使うべきか?
- 配列の一部をコピーしたい:
slice()
メソッド。 - 配列風オブジェクトを配列に変換したい:
Array.from()
メソッド。 - 複数の配列を結合しながらコピーしたい:
concat()
メソッド。 - 特定の条件付きで配列をコピーしたい:
for
ループやforEach()
メソッド。 - シンプルに配列全体をコピーしたい: スプレッド演算子 (
...
)。
使い分けのポイントは、
どの部分をコピーしたいのか、
どんな操作を加えたいのか、
そしてコードのシンプルさや効率性をどこまで考慮したいのか、です。
それぞれのメソッドが持つ特徴を理解し、
目的に応じて適切な方法を選んでください。
まとめ
本記事では、
JavaScriptで配列をコピーする方法を紹介しました!
slice()
や Array.from()
, concat()
メソッドを
使って配列をコピーする方法を解説しました。
これらのメソッドは、
どれも元の配列を変更せずに新しい配列を作成でき、
非常にシンプルで使いやすいです。
また、スプレッド演算子 (...
) も、
配列コピーに便利で簡潔な方法です。
ただし、浅いコピーであるため、
ネストされた配列やオブジェクトには注意が必要です。
さらに、手動でコピーしたい場合はfor
ループや forEach()
を使用することもできます。
どの方法を選ぶかは、
配列の構造や目的に応じて決めると良いでしょう!
以上、誰かの参考になれば!