2016-09-02 1 views
3

Bonne journée!Concaténation de tableau JS pour les résultats d'aplatissement récursif

La tâche consiste à obtenir une version à plat d'un tableau, qui peut inclure une certaine quantité de tableaux imbriqués ainsi que d'autres éléments. Pour l'entrée [1, [2], [3, [[4]]]] sortie [1, 2, 3, 4] attendue. Alerte de spoiler FreeCodeCamp. Naturellement, la solution récursive vient à l'esprit, par exemple .:

function steamrollArray(arr) { 
    var result = []; 
    for(var i = 0; i < arr.length; i++){ 
     //part of interest 
     if (Array.isArray(arr[i])){ 
     var nestedElements = steamrollArray(arr[i]); 
     for(var j = 0; j < nestedElements.length; j ++){ 
      result.push(nestedElements[j]); 
     } 
     //</part of interest>. 
     } else { 
     console.log("pushing: " + arr[i]); 
     result.push(arr[i]); 
     } 
    } 
    return result; 
} 

Et il le fait est chose. Résultat de l'exécution de l'échantillon serait:

pushing: 1 
pushing: 2 
pushing: 3 
pushing: 4 
[1, 2, 3, 4] 

Et la question est: ce qui se passe mal tourné, quand nous utilisons concat d'ajouter nestedElements (ce résultat soi-disant retour du magasin d'appel récursif). Si nous voulons changer d'abord if{} bloc en boucle for (marquée dans le cadre d'intérêt) avec extrait ci-dessous:

if (Array.isArray(arr[i])){ 
    var nestedElements = steamrollArray(arr[i]); 
    result.concat(nestedElements); 
} else { 

nous observons le résultat suivant:

pushing: 1 
pushing: 2 
pushing: 3 
pushing: 4 
[1] 

Ma compréhension était de passer le résultat de chaque appel récursif à la fonction concat, qui ajoutera le tableau retourné au résultat, mais pour une raison quelconque ce n'est pas le cas. Des questions sur cette tâche ont été posées, comme this one, mais celles qui concernent la partie algorithme d'aplatissement, qui n'est pas remise en question ici. Je ne parviens toujours pas à voir la réponse ce qui cause exactement la différence. Il pourrait très bien être quelque chose que j'ai simplement oublié dans une dispute ou à la suite de mon expérience limitée. Désolé si c'est le cas.

+2

Array.concat créera un nouveau tableau et ajoutera les éléments à celui-ci et le résultat est un tout nouveau tableau. Array.concat est immuable, Array.push est mutable. Vous devrez peut-être stocker à nouveau le résultat de l'opération de concatation dans nestedElements. –

+0

Ma leçon ici est de vérifier deux fois la spécification des outils que j'utilise, surtout quand il est si évident que la ligne de code exacte provoque le comportement inattendu. Merci pour votre aide! – shimey

Répondre

4

Array#concat renvoie un nouveau tableau avec le résultat.

Le concat() procédé renvoie une nouvelle matrice constituée de la matrice à laquelle il est appelé joint à la matrice (s) et/ou de valeur (s) fournie en argument.

Vous devez affecter le résultat:

result = result.concat(nestedElements); 
// ^^^^^^ assignment 
1

Je suis intrigué par la réponse acceptée car il ne peut concat deux tableaux. Ce que vous voulez pour un tableau imbriqué est en fait:

var flatArray = [].concat.apply([], yourNestedArray);