2012-01-25 34 views
6

Vui lòng giải thích điều này cho tôi. Tôi đang cố gắng tạo một mảng các mảng với vòng lặp for. Khi nó không hoạt động, tôi đã thử đơn giản hóa mã để hiểu Javascript đang làm gì, nhưng mã đơn giản cũng không có ý nghĩa.Javascript: đẩy mảng lên mảng với vòng lặp

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); 
} 

Tôi hy vọng sẽ thấy [1; 1,2; 1,2,3]. Thay vào đó, tôi nhận được [1,2,3; 1,2,3; 1,2,3]. Tôi nhận được hiện tượng tương tự nếu tôi lặp 0-2 và gán theo chỉ mục.

Trả lời

6

Khi bạn đẩy "sub_array", bạn không đẩy bản sao của nó. Bạn kết thúc với cùng một mảng ba lần trong "super_array". (Tôi phải nói rằng bạn đang đẩy một tham chiếu đến các mảng cùng ba lần.)

Bạn có thể làm điều này:

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

để tạo một bản sao.

0

Đó là cùng một sub_array mà bạn đang thêm vào super_array. Vậy tại sao nó lại khác.

Bạn không tạo mảng mới và đẩy vào siêu dữ liệu.

13

Bạn luôn đẩy tham chiếu đến cùng một mảng vào siêu mảng của mình.

Để giải quyết vấn đề đó, bạn có thể sử dụng slice() sao chép tiểu mảng trước khi đẩy nó:

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); 
} 

EDIT: Như Dan D. chính đáng chỉ ra dưới đây, bạn cũng có thể gọi concat() không có đối số thay vì slice(0). Nó nhanh hơn theo this article (Tôi không đo lường nó bản thân mình):

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

tại sao bạn lại chọn sử dụng '.slice (0)' để sao chép mảng thay vì '.concat()'? có thể nhanh hơn nhưng tôi đã không chắc chắn về hồ sơ. –

+0

Thú vị, theo [blog này] (http://swingpants.com/2009/03/12/fastest-way-to-copy-an-array-concat-or-slice0/) 'concat()' là nhanh hơn . Tôi sẽ đề cập đến nó trong câu trả lời của tôi. Cảm ơn bạn đã bình luận của bạn :) –

0

sub_array được lưu giữ như một tài liệu tham khảo trong super_array này có nghĩa là khi bạn thay đổi sub_array sự thay đổi được phản ánh trong super_array

1

Lưu ý rằng bạn đang đẩy cùng một mảng vào super_array cho mỗi lần lặp trong vòng lặp for. Hãy thử thay vào đó như sau:

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); 
} 
+0

1 cho việc sử dụng slice, mặc dù bạn không cần phải truyền vào bất kỳ tham số nào khi bạn đang sử dụng nó để sao chép toàn bộ mảng arr.slice() === arr.slice (0, arr.length) – wheresrhys

2

. Bạn phải hiểu rằng Array, Objects, Functions, vv là các tham chiếu trong javascript (chỉ các số (Int, Floats, etc) và Strings được truyền "by-value", có nghĩa là, giá trị được sao chép/nhân đôi)! nếu bạn có một số var a=[];, hãy thông báo var b=a và thêm b.push("bla"), sau đó cảnh báo, sẽ hiển thị cho bạn mục nhập "bla", mặc dù bạn đã thêm nó vào b. Nói cách khác; a và b là javascript giống như một ghi chú trên chữ frige từ mẹ nói "cát ở bên trái là dành cho bạn." Và sau đó bạn biết, rằng để có một trái và không chỉ bất kỳ bánh sandwich ngẫu nhiên từ tủ lạnh. Cô cũng có thể viết một ghi chú khác (biến b) trên cửa nhà bạn, để bạn biết đi đâu và tìm bánh sandwich nếu bạn đang vội. Nếu cô ấy đã bị mắc kẹt bánh sandwich vào cửa .. tốt, đó sẽ là vụng về.Và JS cũng nghĩ như vậy về nó :)

vì vậy giải pháp cho vấn đề của bạn cũng như là người bỏ rơi;

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ằng cách xác định lại subarray, bạn tạo tham chiếu mới. Vì vậy, biến b (ghi chú thứ hai trên cửa nhà) bây giờ chỉ theo hướng của một chiếc bánh sandwich khác - có thể là bánh sandwich của bố.

Tôi hy vọng tôi có thể giúp bạn hiểu điều này.

Các vấn đề liên quan