2016-12-11 1 views
1

Ich bin auf der Suche nach etwas Hilfe zu verstehen, warum ich einen Fehler (keine implizite Umwandlung von Nil in String) beim Versuch, eine for-Schleife zu durchsuchen durch ein Array von Buchstaben (und füge sie zu einer resultierenden Zeichenfolge hinzu, die das eigentliche Problem zu sein scheint), aber nicht, wenn ich eine while-Schleife oder "each" für die gleichen Zwecke verwende. Ich habe viele Dokumente durchgesehen, konnte aber keine Antwort darauf finden, warum dies geschieht. Ich verstehe, dass ich einfach die "jede" Methode verwenden und es einen Tag nennen kann, aber ich würde lieber die Ursache als auch den Effekt verstehen (und hoffentlich dieses Problem in der Zukunft vermeiden).Datentyp-Konvertierungsfehler in Ruby for-Schleife

Die folgende Methode funktioniert wie gewünscht: Drucken "Ergebnis", die die ursprüngliche Zeichenfolge ist, nur mit "!" anstelle von Vokalen.

s="helloHELLO" 
result="" 
vowels=["a","e","i","o","u","A","E","I","O","U"] 
string_array=s.split("") 
    string_array.each do |i| 
    if vowels.include?(i) 
     result+="!" 
    else 
     result+=i 
    end 
    end 
puts result 

jedoch mein erster Versuch (unten geschrieben) erwähnt den Fehler wirft oben: „keine implizite Konvertierung von Null in String“ unter Berufung auf Linien 5 und 9.

s="helloHELLO" 
result="" 
vowels=["a","e","i","o","u","A","E","I","O","U"] 
string_array=s.split("") 
    for i in 0..string_array.length 
    if vowels.include?(string_array[i]) 
     result+= "!" 
    else 
     result+=string_array[i] 
    end 
    end 
puts result 

Durch Experimentieren gelang es mir zu lass es funktionieren; und ich habe festgestellt - durch Drucken auf Bildschirm statt in "Ergebnis" zu speichern - dass das Problem während der Verkettung des Zielbriefs mit der Zeichenkette "result" auftritt. Aber warum wird "string_array [i]" (Zeile 9) als NIL und nicht als String betrachtet? Ich fühle mich, als würde ich etwas sehr Offensichtliches vermissen.

Wenn es darauf ankommt: Dies ist nur eine Kata auf CodeWars, die mich zu einer grundlegenden Frage über Datentypen und die Mechanik der For..in-Schleife führen. Dies schien sehr relevant, aber nicht 100% auf die Frage für meine Frage: "for" vs "each" in Ruby.

Vielen Dank im Voraus für die Hilfe.

EDIT:

Okay, ich glaube, ich es herausgefunden. Ich würde trotzdem einige Antworten lieben, um sie zu bestätigen, zu erklären oder regelrecht zu widerlegen.

Ich erkannte, dass, wenn ich die for-Schleife verwenden wollte, sollte ich das Array verwenden, sich als „Bereich“ und nicht als „0..array.length“, etwa so:

s="helloHELLO" 
result="" 
vowels=["a","e","i","o","u","A","E","I","O","U"] 
string_array=s.split("") 
    for i in string_array 
    if vowels.include?(i) 
     result+= "!" 
    else 
     result+=i 
    end 
    end 
puts result 

So ist es, dass, da die "jede" Methodenvariable (in diesem Fall "i") außerhalb des Bereichs des Hauptblocks nicht existiert, ihr Datentyp nach der Bewertung, ob sie in dem "Vokalen" -Array enthalten ist, gleich Null wird?

Antwort

0

Ihre for Schleife:

for i in 0..string_array.length 

Schleifen von 0 bis 10.

Aber string[10] #=> nil weil es kein Element 10 im Index und dann auf Linie 9 versuchen Sie nil-result

hinzufügen

Sie können nicht nil zu einer Zeichenfolge wie folgt hinzufügen, müssen Siekonvertierenzu einem String explizit also der Fehler. Der beste Weg, um dieses Problem zu beheben, ist auf Ihre for-Schleife zu ändern:

for i in 0..string_array.length-1 

Dann ist Ihre Schleife am letzten Punkt beenden wird, string[9].

0

Sie wurden von dem klassischen Fehler übertroffen, wenn Sie ein Array beginnend mit dem Index 0 durchlaufen, anstelle der Länge als Endposition sollte es länge-1 sein. Aber es scheint, als ob Sie aus einer anderen Programmiersprache kommen, Ihr Code ist nicht Rubysque, ein "For" zum Beispiel wird selten verwendet. Ruby ist eine höhere Sprache als die meisten anderen, es hat viele eingebaute Lösungen, wir nennen es "gezuckert", weil Ruby uns Programmierer glücklich machen soll. Was Sie erreichen möchten, kann in nur einer Zeile erfolgen.

"helloHELLO".scan(/[aeoui]/i).count 

Eine Erklärung: die wörtliche Array „hallo hallo“ ist ein String, ein Objekt der String-Klasse bedeutet, und als solche eine Menge von Methoden haben, können Sie verwenden, wie Scan, der die Zeichenfolge für die regelmäßige Scans Ausdruck/[aeoui]/was bedeutet, dass eines der Zeichen in [] eingeschlossen ist, das i am Ende macht es fallinsensitiv, so dass du AEOUI nicht hinzufügen musst. Der Scan gibt ein Array mit den passenden Zeichen zurück, ein Objekt der Array-Klasse hat die Methode count, was uns die ... Ja, sobald Sie die Drift haben, ist es einfach, Sie können Methoden aneinanderreihen, die aufeinander wirken.