2016-06-22 7 views
1

In einer anderen Frage von mir jemand eine wirklich coole Lösung, wie ein n-tes verschachteltes Array in ein Array abgeflacht. Da ich keinen langen Chat beginnen wollte und ich immer noch nicht wirklich verstehe, was dieser Code macht, dachte ich, ich würde fragen.Verflacht Array Array-Code

Also mein Eindruck ist, dass zuerst in diesem Fall unser Array Länge 2 hat, und dann wird es 1 in der While-Schleife. Wir prüfen dann ist array[1], ist ein Array. Es ist so, dass wir fortfahren. Jetzt bin ich hier ein bisschen verwirrt. Ich glaube, wir rufen die flatten Funktion wieder auf, so dass wir in die verschachtelten Arrays gelangen können, aber ich bin immer noch irgendwie unklar bezüglich der Argumentation. Wir nehmen dann array[1] und schneiden es, hier schneidet nicht gerade schneiden, das ganze array[l] sowieso bekommen? da wir von der 0. Position bis zum Ende gehen, da slice() keine Parameter hat.

function flatten(array) { 
    var l = array.length, temp; 
    while (l--) { 
     if (Array.isArray(array[l])) { 
      flatten(array[l]); 
      temp = array[l].slice(); 
      temp.unshift(1); 
      temp.unshift(l); 
      [].splice.apply(array, temp); 
     } 
    } 
} 


var array = [['1', '2', '3'], ['4', '5', ['6'], ['7', '8']]]; 

flatten(array); 

console.log(array); 

https://jsfiddle.net/curw7mdp/

Antwort

1

Also werde ich davon ausgehen, dass Sie die Grundlagen der Rekursion verstehen. Ich werde dich Zeile für Zeile durchgehen.

var l = array.length, temp; 

Deklariert l gleich der Länge des Arrays und deklariert temp.

while (l--) 

Diese dekrementiert l nach der Iteration der Schleife (im Gegensatz zu tun, bevor es -L);

if (Array.isArray(array[l])) 

Dies überprüft, ob das 'th-Element im Array ein anderes Array ist. Dies ist wichtig, weil dies bedeutet, dass dieses Element nicht flach ist.

flatten(array[l]); 

Dies ist, wo es Spaß bekommt, rekursiv die Funktion selbst nennt, so dass es nun den Sub-Array durchqueren kann. Und wenn das Sub-Array ein anderes Array enthält, kann es tiefer gehen. Ich glaube, das ist Kopfrekursion.

temp = array[l].slice(); 

Sieht etwas komisch aus, aber das erlaubt uns, das Array in eine neue Variable namens temp zu extrahieren.

temp.unshift(1); 
temp.unshift(l); 
[].splice.apply(array, temp); 

Dies ist auch ein sehr janky Art des Schreibens Dinge, sondern es setzt im Grunde 1 und L wie die erste auf die Elemente in dem temporären Array, und dann ruft es Spleiß auf Array, mit Temperatur als die Parameter. Nur die ersten beiden Elemente von temp werden als Parameter übergeben (die beiden, die wir vor einer Sekunde eingegeben haben), so dass es im Grunde genommen das Sub-Array entfernt und durch die abgeflachte Version ersetzt.

+0

Nein, die Array-Länge beginnt bei 3 und jede Iteration der Schleife dekrementiert sie. [] .splice macht nichts alleine, du wirst die Methode apply lesen müssen. Es ist eine sehr seltsame Syntax, ich bin mir nicht sicher, der beste Weg, es zu erklären. – master565

+0

Entschuldigung. Ja, es ist ein 2-Elemente-Array. Ich habe es falsch verstanden. – master565

+0

Auch im Zusammenhang mit der Anwendungsfunktion. Splice ist eine Methode, die auf Arrays funktioniert, und so [] ist ein leeres Array, auf dem die Funktion aufgerufen werden kann. – master565

0

Referenzen: splice(), apply(), unshift()

Siehe Anmerkungen zur detaillierten Erläuterung.

function flatten(array) { 

    // put the length of the array in l 
    // and create a temp variable with nothing in it 
    var l = array.length, temp; 

    // while(l--) will iterate through 
    // each item in the array backwards 
    // this is just a little faster than doing 
    // for(var i=0; i<array.length; i++) 
    while (l--) { 

     // The current item in the while loop is array[l] 
     // (that's an L, by the way, not a one) 
     // so this is saying "if current item is an array...." 
     if (Array.isArray(array[l])) { 

      // we call the function again (recursion) 
      // if this is an array. eventually, one of 
      // the inner items will be something other 
      // than an array and the recursion will stop 
      flatten(array[l]); 

      // when you call slice() with no parameters 
      // all it does is create a copy of the entire array 
      // and then we store it in temp 
      temp = array[l].slice(); 

      // adds the number 1 to the begining of the array 
      // after we unshift one more time below, 
      // this will become the second parameter for the 
      // splice() call below, which is the number of 
      // items to delete 
      temp.unshift(1); 

      // adds the current index to the begining of the array 
      // this will be the first argument passed to splice() 
      // below, the first argument for splice is the 
      // index to start splicing.. 
      temp.unshift(l); 

      // apply()'s first argument is context, in this case 
      // passing "array" as the context means the action will 
      // be performed on the array variable, 
      // which is the original arrray.. 
      // apply()'s second argumetn is an array, each item 
      // of the array is passed in order to the function 
      // as arguments 
      // So basically this is saying.. "remove the current 
      // index (which is an array) and replace it with each 
      // of the items that were in that array 
      [].splice.apply(array, temp); 
     } 
    } 
} 
+0

erinnern, wir sind rückwärts (l--) so auf der ersten Iteration l wird = 3 –

+0

lol, mein Fehler, du hast Recht, es gibt 2 Elemente in der Anordnung, und wir l-- vor jedem Iteration, so wird bei der ersten Iteration tatsächlich = 1, wie Sie ursprünglich angegeben haben. –

+0

Wenn Sie 'while()' verwenden, erfolgt die Dekrementierung vor der Schleife, nicht danach. es wird 1 auf der ersten Iteration sein. –