2017-02-12 2 views
1

Im Folgenden habe ich zwei Code-Snippets zur Verfügung gestellt, die meiner Meinung nach dasselbe tun sollten. Im ersten Snippet bekomme ich einen "Null" -Wert. Ich stelle mir das vor, weil ein null Wert in die Funktion als arr übergeben wird, wenn ich steamrollArray(arr[0]) auf [] rufe, den Nullwert in den Akkumulator schiebend.Nullwert in Array-Flattening-Rekursion mit `for` vs` slice`: Warum unterscheiden sich die Rückgabewerte dieser beiden Funktionen?

Was ich nicht weiß, und ich hoffe, ich kann etwas Hilfe haben, ist, was könnte eine elegante Möglichkeit sein, dieses spezielle Problem zu vermeiden?

Ich möchte beide Funktionen geben die gleiche Ausgabe, wenn die gleiche Eingabe gegeben.

Als Hilfestellung: Mich würde interessieren, ob mich jemand auf eine Methode hinweist, diese beiden Methoden gegeneinander abzugrenzen - darüber weiß ich nichts, außer dass es "eine Sache ist "und es wäre für mich im Allgemeinen hilfreich zu verstehen, wie man so etwas macht, und speziell, wie man das mit diesem Problem tun könnte.

Als weiterer Hilfspunkt: Gibt es einen interaktiven Javascript-Interpreter, genauso wie Sie einen interaktiven Python-Interpreter bekommen (wo Sie mit den Befehlen in der Befehlszeile spielen/testen können)?

Version 1: "natürliche" Rekursion - liefert [1,null,2,3]

function steamrollArray(arr) { 
 
    // I'm a steamroller, baby 
 
    //recursive (is an array) 
 
    var accum = []; 
 
    if (Array.isArray(arr)) { 
 
    accum = accum.concat(steamrollArray(arr[0])); 
 
    if (arr.length > 1) { 
 
     accum = accum.concat(steamrollArray(arr.slice(1))); 
 
    } 
 
    } else { 
 
    accum.push(arr); 
 
    } 
 
    return accum; 
 
} 
 

 
console.log(
 
    steamrollArray([1, [], [3, [[4]]]]) 
 
);

Version 2: for Rekursionsschleife - liefert [1,2,3]

function steamrollArray(arr) { 
 
    // I'm a steamroller, baby 
 
    //recursive (is an array) 
 
    var accum = []; 
 
    for (var i = 0; i < arr.length; i++) { 
 
    if (Array.isArray(arr[i])) { 
 
     accum = accum.concat(steamrollArray(arr[i])); 
 
    } else { 
 
     accum.push(arr[i]); 
 
    } 
 
    } 
 
    return accum; 
 
} 
 

 
console.log(
 
    steamrollArray([1, [], [3, [[4]]]]) 
 
);

+1

"* Gibt es einen interaktiven Javascript-Interpreter *" - haben Sie versucht, 'F12' in Ihrem Browser zu drücken? ':)' (In Chrome müssen Sie möglicherweise auf die Registerkarte 'Console' klicken.) – apsillers

+0

@apsillers genau das, was ich gesucht habe, danke! Ich wusste, dass es ein solches Feature in Chrom geben musste. – NotAnAmbiTurner

Antwort

3

In Version 1 Sie drängen arr[0], ohne zu überprüfen, ob es ein Element innerhalb arr[0] ist. So beim zweiten Aufruf zu steamrollArray, wo Sie ein leeres Array [] sind vorbei, wird arr[0] undefiniert:

var arr = []; 
 

 
console.log(arr[0]);

Warum dies nicht in Version geschieht 2? Es ist, weil Sie eine for Schleife haben, die die push Anrufe einwickelt (for(var i = 0; i < arr.length...). Wenn also das leere Array übergeben wird, wird die Schleife for nie eingegeben. weil 0 < 0false ist.

können Sie beheben Version 1 durch den push Anruf innerhalb einer Verpackung if-Anweisung wie folgt aus: (die Push passieren wird, wenn steamrollArray mit dem Argument arr[0] aufgerufen)

if(arr.length) // if length is not 0 
    accum = accum.concat(steamrollArray(arr[0])); 

Ancillary 2:NodeJs ist eine großartige Javascript-Laufzeitumgebung. Es kommt mit einer Befehlszeilenschnittstelle. Versuch es!

Verwandte Themen