【问题标题】:Javascript: push array onto array with for loopJavascript:使用for循环将数组推入数组
【发布时间】:2012-02-18 19:37:56
【问题描述】:

请给我解释一下。我正在尝试使用 for 循环创建一个数组数组。当它不起作用时,我尝试简化代码以了解 Javascript 在做什么,但简单的代码也没有意义。

function test(){
    var sub_array = [];
    var super_array =[];
    for (var i=1;i<=3;i++){
        sub_array.push(i);
        super_array.push(sub_array);
    }
    alert(super_array);
}

我希望看到 [1; 1,2; 1,2,3]。 相反,我得到 [1,2,3; 1,2,3; 1,2,3]。 如果我循环 0-2 并按索引分配,我会得到同样的现象。

【问题讨论】:

    标签: javascript arrays loops for-loop


    【解决方案1】:

    当您推送“sub_array”时,您并没有推送它的副本。您最终在“super_array”中使用相同的数组三次。 (我应该说您将 reference 推送到同一个数组三次。)

    你可以这样做:

        // ...
        super_array.push(sub_array.slice(0));
    

    制作副本。

    【讨论】:

      【解决方案2】:

      您要添加到 super_array 的 sub_array 相同。那么为什么它必须有所不同。

      您没有创建新数组并推入 super_array。

      【讨论】:

        【解决方案3】:

        您总是将同一个数组的引用推送到您的超级数组中。

        要解决这个问题,您可以在推送之前使用slice() 克隆子数组:

        function test() {
            var sub_array = [];
            var super_array = [];
            for (var i = 1; i <= 3; i++) {
                sub_array.push(i);
                super_array.push(sub_array.slice(0));
            }
            alert(super_array);
        }
        

        编辑:正如 Dan D. 在下面正确指出的那样,您也可以不带参数调用 concat() 而不是 slice(0)。根据this article 更快(我自己没有测量):

        for (var i = 1; i <= 3; i++) {
            sub_array.push(i);
            super_array.push(sub_array.concat());
        }
        

        【讨论】:

        • 为什么选择使用.slice(0)而不是.concat()来复制数组?这可能更快,但我不确定我所做的分析。
        • 有趣,根据this blog concat() 更快。我会在我的回答中提到它。谢谢你的评论:)
        • 这个解决方案让我免于扯掉头发。谢谢。
        【解决方案4】:

        sub_array 存储为super_array 中的引用,这意味着当您更改sub_array 时,更改将反映在super_array

        【讨论】:

          【解决方案5】:

          请注意,对于 for 循环中的每次迭代,您都将相同的数组推入 super_array。请尝试以下方法:

          function test(){
              var sub_array = [];
              var super_array =[];
              for (var i=1;i<=3;i++){
                  sub_array = sub_array.slice(0,sub_array.length);
                  sub_array.push(i);
                  super_array.push(sub_array);
              }
              alert(super_array);
          }
          

          【讨论】:

          • +1 用于使用 slice,虽然在使用它克隆整个数组时不需要传入任何参数 arr.slice() === arr.slice(0, arr.length)
          【解决方案6】:

          好吧。您必须了解,数组、对象、函数等是 javascript 中的引用(只有数字(Int、Floats 等)和字符串是“按值”传递的,这意味着该值被复制/复制)! 如果您有一个var a=[];,请说出var b=a 并添加b.push("bla"),然后提醒a,将向您显示“bla”条目,即使您已将其添加到b。 换一种说法; a 和 b 是 javascript,就像妈妈在冰箱上写的“左边的三明治是给你的”。然后你知道,从冰箱里拿走左边的三明治,而不是随便拿的三明治。她还可以在你家的门上写另一个便条(变量 b),这样如果你赶时间,你就知道去哪里找三明治。 如果她会在门上贴一个三明治……好吧,那将是不合时宜的。 JS 也是这么想的 :)

          所以你的问题的解决方案是休闲;

          function test(){
              var super_array =[];
              for (var i=1;i<=3;i++){
                  var subarray=[];
                  for (var u=1;u<=4-i;u++){
                      sub_array.push(u);
                      super_array.push(subarray);
                  }
              }
              alert(super_array);
          }
          

          通过重新定义子数组,您可以创建一个新的引用。所以变量 b(房子门上的第二个音符)现在指向另一个三明治的方向——也许是爸爸的三明治。

          希望我能帮助你理解这一点。

          【讨论】:

            猜你喜欢
            • 2015-10-24
            • 2017-12-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-05-11
            相关资源
            最近更新 更多