#この記事でやること
pythonを触っているときにcopyを使えば二次元配列も簡単にコピーできることに感動しました。
以前にjavascriptで同じことをやろうと思ったときに詰まった経験があるので、
javascriptの二次元配列やオブジェクトの配列をコピーする方法を残しておこうと思います。
#はじめに
まず、javascriptである配列を別変数に代入した場合、その変数の値を変更すると元の配列にも影響します。
deepcopy.js
const arr1 = [0, 1, 2];
const arr2 = arr1;
arr2[0] = 5;
console.log(arr1); // [5, 1, 2]
このパターンでよく使われるのがこちらです。
deepcopy.js
// パターン1
const arr1 = [0, 1, 2];
const arr2 = [].concat(arr1);
arr2[0] = 5;
console.log(arr1); // [0, 1, 2]
// パターン2
const arr1 = [0, 1, 2];
const arr2 = arr1.map( item => item);
arr2[0] = 5;
console.log(arr1); // [0, 1, 2]
// パターン3
const arr1 = [0, 1, 2];
const arr2 = Array.from(arr1);
arr2[0] = 5;
console.log(arr1); // [0, 1, 2]
// パターン4
const arr1 = [0, 1, 2];
const arr2 = [...arr1];
arr2[0] = 5;
console.log(arr1); // [0, 1, 2]
などです。
この他にもいくつか方法はあるかもしれません。
しかし、これらの方法でも二次元配列ではうまくいきません。
deepcopy.js
const arr1 = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
];
const arr2 = [...arr1];
arr2[0] = [1, 2, 3];
console.log(arr1);
// [[0, 1, 2],
// [3, 4, 5],
// [6, 7, 8]]
上記の例の場合では元の配列arr1には影響がありません。
しかし次の場合にうまく動作しません。
deepcopy.js
const arr1 = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
];
const arr2 = [...arr1];
arr2[0][0] = 5;
console.log(arr1);
// [[5, 1, 2],
// [3, 4, 5],
// [6, 7, 8]]
この場合は元の配列に影響を及ぼしてしまいます。
#二次元配列の場合
そこで二次元配列の場合は次のようにします。
deepcopy.js
// パターン1
const arr1 = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
];
const arr2 = arr1.map( item => [].concat(item));
arr2[0][0] = 5;
console.log(arr1);
// [[0, 1, 2],
// [3, 4, 5],
// [6, 7, 8]]
// パターン2
const arr1 = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
];
const arr2 = arr1.map( item => [...item]);
arr2[0][0] = 5;
console.log(arr1);
// [[0, 1, 2],
// [3, 4, 5],
// [6, 7, 8]]
このようにするとうまくいきます。
オブジェクトの配列なども同様にすれば良いです。
deepcopy.js
const arr1 = [
{ name: 'hoge', age: 19 },
{ name: 'fuga', age: 25 },
{ name: 'foo', age: 22 }
];
const arr2 = arr1.map( item => Object.assign({}, item));
arr2[0].name = 'fuga';
console.log(arr1);
// {name: "hoge", age: 19}
// {name: "fuga", age: 25}
// {name: "foo", age: 22}
#まとめ
これをdeepcopyと読んでも良いのでしょうか?
javascriptでそのような配列を取り扱い、またコピーする必要がある機会に出くわすかはわかりませんが、次元が大きくなるにつれコードがとんでもなくなりそうです。