94

これは「ディープコピー」とも呼ばれ、いくつかの記事を見つけました。最も近いのはこれのようですが、jQuery用です-私はライブラリなしでこれを行おうとしています。

また、2つの場所で、次のようなことが可能であることも確認しました。

arr2 = JSON.decode(JSON.encode(arr1));

しかし、それは明らかに非効率的です。各値を個別にループしてコピーすることも可能であり、すべての配列を繰り返し処理します。それも疲れて非効率的なようです。

では、JavaScriptの多次元配列をコピーするための最も効率的な非ライブラリの方法は[[a],[b],[c]]何でしょうか。必要に応じて、「非IE」方式に完全に満足しています。

ありがとう!

4

4 に答える 4

107

未知のレベルの深さまで配列の配列を処理しているように聞こえますが、常に1つのレベルの深さで処理するだけでよいので、簡単かつ高速に使用できます.slice()

var newArray = [];

for (var i = 0; i < currentArray.length; i++)
    newArray[i] = currentArray[i].slice();

または、ループ.map()の代わりに使用します。for

var newArray = currentArray.map(function(arr) {
    return arr.slice();
});

したがって、これは現在の配列を繰り返し、ネストされた配列の浅いコピーの新しい配列を構築します。次に、次のレベルの深さに進むと、同じことを行います。

もちろん、配列と他のデータが混在している場合は、スライスする前にそれが何であるかをテストする必要があります。

于 2012-12-07T04:08:31.633 に答える
22

JSON.stringifyJSON.parseよりもencodeどれだけ優れているかはわかりませんdecodeが、試してみることができます:

JSON.parse(JSON.stringify(array));

私が見つけた他の何か(私はそれを少し変更しますが):

http://www.xenoveritas.org/blog/xeno/the-correct-way-to-clone-javascript-arrays

function deepCopy(obj) {
  if (typeof obj == 'object') {
    if (isArray(obj)) {
      var l = obj.length;
      var r = new Array(l);
      for (var i = 0; i < l; i++) {
        r[i] = deepCopy(obj[i]);
      }
      return r;
    } else {
      var r = {};
      r.prototype = obj.prototype;
      for (var k in obj) {
        r[k] = deepCopy(obj[k]);
      }
      return r;
    }
  }
  return obj;
}
于 2012-12-07T03:38:51.450 に答える
6

あなたがパフォーマンスを求めたように、私はあなたも非一般的な解決策を使うだろうと思います。既知のレベル数の多次元配列をコピーするには、最も簡単な解決策であるネストされたforループを使用する必要があります。2次元配列の場合、次のようになります。

var len = arr.length,
    copy = new Array(len); // boost in Safari
for (var i=0; i<len; ++i)
    copy[i] = arr[i].slice(0);

高次元の配列に拡張するには、再帰を使用するか、ネストされたforループを使用します。

ネイティブsliceメソッドは、カスタムのforループよりも効率的ですが、ディープコピーを作成しないため、最下位レベルでのみ使用できます。

于 2012-12-07T04:13:00.933 に答える
4

同じノードに2回アクセスしない再帰的アルゴリズムは、(少なくともブラウザーでは)javascriptを使用した場合とほぼ同じくらい効率的です。他の言語の特定の状況では、メモリのチャックをコピーすることで回避できる場合がありますが、javascriptは明らかにそうではありません。その能力はありません。

すでにそれを行っている人を見つけ、その実装を使用して、正しく理解できるようにすることをお勧めします。定義する必要があるのは1回だけです。

于 2012-12-07T03:38:54.063 に答える