web-dev-qa-db-fra.com

Javascript: Envoie un tableau dans un tableau avec une boucle for

S'il te plaît, explique-moi. J'essaie de créer un tableau de tableaux avec une boucle for. Quand cela ne fonctionnait pas, j'ai essayé de simplifier le code pour comprendre ce que fait Javascript, mais le code simple n'a pas de sens non plus.

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

Je m'attends à voir [1; 1,2; 1,2,3]. Au lieu de cela, je reçois [1,2,3; 1,2,3; 1,2,3]. Je reçois le même phénomène si je boucle 0-2 et attribue par index.

8
Eric Porterfield

Vous insérez toujours une référence au même tableau dans votre super-tableau.

Pour résoudre ce problème, vous pouvez utiliser slice () pour cloner le sous-tableau avant de le pousser:

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: Comme Dan D. le souligne à juste titre ci-dessous, vous pouvez également appeler concat () sans arguments au lieu de slice(0). C'est plus rapide selon cet article (je ne l'ai pas mesuré moi-même):

for (var i = 1; i <= 3; i++) {
    sub_array.Push(i);
    super_array.Push(sub_array.concat());
}
15
Frédéric Hamidi

Lorsque vous appuyez sur "sub_array", vous ne poussez pas une copie de celle-ci. Vous vous retrouvez avec le même tableau trois fois dans "super_array". (Je devrais dire que vous poussez une référence vers le même tableau trois fois.)

Vous pourriez faire ceci:

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

faire une copie.

6
Pointy

bien. Vous devez comprendre que les tableaux, les objets, les fonctions, etc. sont des références en javascript (seuls les nombres (Int, Floats, etc.) et les chaînes sont passés "par valeur", ce qui signifie que la valeur est copiée/dupliquée)! si vous avez un var a=[];, dites var b=a et ajoutez b.Push("bla"), puis alerter a, vous montrera l'entrée "bla", même si vous l'avez ajoutée à b. En d'autres termes; a et b sont à javascript comme une note sur le frigo de maman en disant "le sandwhich sur la gauche est pour vous." Et puis vous savez que prendre celui de gauche et pas n'importe quel sandwich pris au hasard dans le réfrigérateur. Elle aurait également pu écrire une autre note (variable b) sur la porte de votre maison pour que vous sachiez où aller chercher le sandwich si vous êtes pressé. Si elle avait collé un sandwich à la porte… eh bien, ce serait pénible. Et JS pense la même chose à ce sujet :)

la solution à votre problème est donc comme des jachères;

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

en redéfinissant le sous-tableau, vous créez une nouvelle référence. Ainsi, la variable b (la deuxième note sur la porte du boîtier) pointe maintenant vers un sandwich différent - peut-être le sandwich de papa.

J'espère que je pourrais vous aider à comprendre cela.

2
japrescott

Notez que vous insérez le même tableau dans super_array à chaque itération de la boucle for. Essayez plutôt ce qui suit:

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
Thomas Johan Eggum

C'est le même sous-tableau que vous ajoutez au super-tableau. Alors pourquoi cela doit-il être différent?.

Vous ne créez pas de nouveau tableau et ne passez pas dans un super_array.

0
Selvakumar Arumugam

sub_array est stocké en tant que référence dans super_array, cela signifie que lorsque vous modifiez sub_array, la modification est reflétée dans super_array

0
James Wiseman