【问题标题】:Copy an arbitrary n-dimensional array in JavaScript?在 JavaScript 中复制任意 n 维数组?
【发布时间】:2012-06-08 00:29:47
【问题描述】:

我基本上是在寻找一个通用函数 copy(array),它将返回相同的 n 维数组,而不引用前一个数组。

【问题讨论】:

  • 无...但不要评判我,我是 javascript 的初学者。我只看过这个:stackoverflow.com/questions/419858/…,这对我的情况来说还不够笼统。
  • @Ognjen - Java 不是 JavaScript。
  • 顺便说一句,我正在将一些代码从 java 移植到 js,如果你想知道我为什么需要这个 :)
  • 您是否必须拥有任意类型的任意副本?如果知道数组的类型和维数,问题就简单多了。
  • @Derek - 浅拷贝会复制顶级项目,但如果有任何比这更深的项目(例如数组中的数组或属性中的数组),它不会制作副本其中(它们最终成为对相同对象的引用)。深拷贝确保每个级别的每个项目都是一个副本。深拷贝通常使用递归。

标签: javascript arrays deep-copy


【解决方案1】:

这适用于数组,不适用于嵌套对象(不是数组):

function copy(arr){
    var new_arr = arr.slice(0);
    for(var i = new_arr.length; i--;)
        if(new_arr[i] instanceof Array)
            new_arr[i] = copy(new_arr[i]);
    return new_arr;
}

像这样使用它:

var arr = [
   [[1,2,3],[75]], 100,
   [[[1]]], [],
   [1,[2,[3],4],5], 6, 7, 8
];

var new_arr = copy(arr);

【讨论】:

    【解决方案2】:

    使用 jQuery(适用于数组和“普通”对象):

    var a = [[1,[2,3]],[4]];
    var b = $.extend(true, [], a);
    a[0][0] = 42;             // modify object in a
    alert(JSON.stringify(b)); // [[1,[2,3]],[4]]
    

    或 JSON 直接(如果所有对象都是 JSON 可化的):

    var a = [[1,[2,3]],[4]];
    var b = JSON.parse(JSON.stringify(a))
    a[0][0] = 42;             // modify object in a
    alert(JSON.stringify(b)); // [[1,[2,3]],[4]]
    

    旧版本的 IE(8?7?)将需要一个用于 JSON 对象的填充程序。

    【讨论】:

    • 小注:如果值为undefined,则不会转成JSON。
    【解决方案3】:

    我只是想补充一下 Paulpro 的答案。请注意,这与他的答案相同,只是我将 copy(new_arr[i]) 更改为 copy(arr[i]),并将 new_arr.length 更改为 arr.length。

    function copy(arr){
    var new_arr = arr.slice(0);
    for(var i = arr.length; i--;)
        if(new_arr[i] instanceof Array)
            new_arr[i] = copy(arr[i]);
    return new_arr;
    }
    

    copy(new_arr[i]) 起作用的原因是 .slice 复制了 arr[i] 指向的内容,使它们相等。

    此外,虽然 Paulpro 的答案适用于所有情况,但如果碰巧多维数组的每个维度的每个成员都是数组或非数组,您可以通过仅对非数组维度进行切片来提高效率。 我的意思是复制一个指针数组有什么意义,这些指针数组只会被以下递归覆盖?

    function copy(arr){
    if(arr[0] instanceof Array){
        var new_arr = new Array(arr.length);
        for(var i = arr.length; i--;)
            new_arr[i] = copy(arr[i]);
    }
    else{var new_arr = arr.slice(0);}
    return new_arr;
    }
    

    【讨论】:

      【解决方案4】:

      这是我克隆多维数组的解决方案;实际上我必须发明Array.prototype.clone()才能发明一个函数来生成N维数组并用一个值初始化它。

      Array.prototype.clone = function(){
        return this.reduce((p,c,i) => (p[i] = Array.isArray(c) ? c.clone() : c, p),[])
      }
      
      function arrayND(...n){
        return n.reduceRight((p,c) => c = (new Array(c)).fill(true).map(e => Array.isArray(p) ? p.clone() : p ));
      }
      
      var arr = arrayND(...[4,4,4],8); //last argument is the initializing value
      arr[0][1][3] = "eight";
      console.log(JSON.stringify(arr));

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-07-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-22
        • 2012-09-17
        • 2020-03-20
        • 2016-11-03
        相关资源
        最近更新 更多