4


2

JavaScriptで多次元配列を複製する

メインの配列に影響を与えずにクローン配列を操作できるように、多次元配列のクローンを作成したい。

そのために次の関数を使用しています。

Array.prototype.clone = function () {
   var newArray = new Array(this.length);
     for(var i=0; i < this.length; i++ ){
        newArray[i] = this[i];
   }
   return newArray;
};

しかし、問題は配列プロトタイプを使用しているため、すべての配列を複製するためです。

3 回答


10


vsyncは正しいです、私の最初の答えは `var a = [[1,2]、[3,4]];`を処理しません+だからここに改良版があります

var a = [[1,2],[3,4]];
Array.prototype.clone = function() {
    var arr = this.slice(0);
    for( var i = 0; i < this.length; i++ ) {
        if( this[i].clone ) {
            //recursion
            arr[i] = this[i].clone();
        }
    }
    return arr;
}

var b = a.clone()

console.log(a);
console.log(b);

b[1][0] = 'a';

console.log(a);
console.log(b);

//[[1, 2], [3, 4]]
//[[1, 2], [3, 4]]
//[[1, 2], [3, 4]]
//[[1, 2], ["a", 4]]


3


再帰を使用する必要があります

var a = [1,2,[3,4,[5,6]]];

Array.prototype.clone = function() {
    var arr = [];
    for( var i = 0; i < this.length; i++ ) {
//      if( this[i].constructor == this.constructor ) {
        if( this[i].clone ) {
            //recursion
            arr[i] = this[i].clone();
            break;
        }
        arr[i] = this[i];
    }
    return arr;
}

var b = a.clone()

console.log(a);
console.log(b);

b[2][0] = 'a';

console.log(a);
console.log(b);

/*
[1, 2, [3, 4, [5, 6]]]
[1, 2, [3, 4, [5, 6]]]
[1, 2, [3, 4, [5, 6]]]
[1, 2, ["a", 4, [5, 6]]]
*/

ただし、元の配列の他のオブジェクトは参照によってコピーされます


2


このアプローチはmeouwのアプローチよりも優れていることがわかりました。

var source = [
  [1, 2, {c:1}],
  [3, 4, [5, 'a']]
];

// Create a new method ontop of the "Array" primitive prototype:
Array.prototype.clone = function() {
  function isArr(elm) {
    return String(elm.constructor).match(/array/i) ? true : false;
  }

  function cloner(arr) {
    var arr2 = arr.slice(0),
        len = arr2.length;

    for (var i = 0; i < len; i++)
      if (isArr(arr2[i]))
        arr2[i] = cloner(arr2[i]);

    return arr2;
  }
  return cloner(this);
}

// Clone
var copy = source.clone();

// modify copy
copy[0][0] = 999;

console.dir(source);
console.dir('**************');
console.dir(copy);

もう1つの方法は、プリミティブ+

値として( String、` Numbers`、 Objects):

var source = [
  [1,2, {a:1}],
  ["a", "b", ["c", 1]]
];

// clone "srouce" Array
var copy = JSON.parse(JSON.stringify(source));

// modyfy clone
copy[0][0] = 999;

// print both arrays
console.dir(copy)
console.log('***********')
console.dir(source)