2012-01-25 1 views
6

Per favore, spiegamelo. Sto cercando di creare una serie di array con un ciclo for. Quando non ha funzionato, ho provato a semplificare il codice per capire cosa sta facendo Javascript, ma neanche il codice semplice ha senso.Javascript: push array su array con ciclo for

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

Mi aspetto di vedere [1; 1,2; 1,2,3]. Invece ottengo [1,2,3; 1,2,3; 1,2,3]. Ottengo lo stesso fenomeno se eseguo il ciclo 0-2 e assegno per indice.

risposta

6

Quando si preme "sub_array", non si preme un copia di esso. Finisci con lo stesso array tre volte in "super_array". (Dovrei dire che si sta spingendo un riferimento allo stesso array tre volte.)

Si potrebbe fare questo:

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

per fare una copia.

0

È lo stesso sottoarray che si sta aggiungendo a super_array. Quindi, perché deve essere diverso.

Non si sta creando un nuovo array e si spinge in un super array.

13

Spingete sempre un riferimento allo stesso array nel vostro super-array.

Per risolvere questo problema, è possibile utilizzare slice() per clonare il sub-array prima spingendola:

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: Come Dan D. sottolinea giustamente qui di seguito, è possibile anche chiamare concat() senza argomenti invece di slice(0). E 'più veloce in base alle this article (I non ha misurato io stesso):

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

perché hai scelto di usare '.slice (0)' per copiare l'array piuttosto che '.concat()'? che potrebbe essere più veloce ma la profilazione che ho fatto non era sicura. –

+0

Interessante, secondo [questo blog] (http://swingpants.com/2009/03/12/fastest-way-to-copy-an-array-concat-or-slice0/) 'concat()' è più veloce . Lo menzionerò nella mia risposta. Grazie per il tuo commento :) –

0

sub_array viene memorizzato come riferimento in super_array questo significa che quando si cambia sub_array il cambiamento si riflette all'interno super_array

1

Nota che siete spingendo lo stesso array in super_array per ogni iterazione nel ciclo for. Prova invece:

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 per l'uso di slice, sebbene non sia necessario passare alcun parametro quando lo si utilizza per clonare l'intero array arr.slice() === arr.slice (0, arr.Length) – wheresrhys

2

bene. Devi capire che la matrice, gli oggetti, le funzioni, ecc. Sono riferimenti in javascript (solo i numeri (Int, Floats, ecc.) E le stringhe vengono passati "in base al valore", il che significa che il valore è copiato/duplicato! se si dispone di , e si dice var b=a e si aggiunge b.push("bla"), quindi l'avviso a, vi mostrerà la voce "bla", anche se l'avete aggiunta a b. In altre parole; aeb è di javascript come una nota sulla frittura da mamma che dice "il sandwhich sulla sinistra è per te". E poi sai, quello di prendere quello di sinistra e non solo qualsiasi sandwich casuale dal frigo. Potrebbe anche aver scritto un'altra nota (variabile b) sulla porta della tua casa, in modo da sapere dove andare e cercare il panino se sei di fretta. Se lei avesse bloccato un sandwich alla porta ... beh, sarebbe stato imbarazzante.E JS la pensa allo stesso modo :)

quindi la soluzione al tuo problema è come maggese;

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

ridefinendo il subarray, si crea un nuovo riferimento. In modo che la variabile b (la seconda nota sulla porta della casa) ora punti nella direzione di un sandwich diverso - forse il sandwich di papà.

Spero di poterti aiutare a capire questo.