2016-08-08 40 views
1

Nach herumspielen mit den ganzen Morgen (ich bin noch neu zu diesem Thema), habe ich beschlossen, die Experten zu fragen.mit der case-Anweisung, um einen Index zu finden und es

Dies ist die Suche:

Sie werden ein Wort gegeben werden. Ihre Aufgabe ist es, das mittlere Zeichen des Wortes zurückzugeben. Wenn die Länge des Wortes ungerade ist, geben Sie das mittlere Zeichen zurück. Wenn die Länge des Wortes gerade ist, geben Sie die mittleren 2 Zeichen zurück. Diese

ist das, was ich bisher:

def median(string)       
     array = string.split(//) 
     case array 
     when array.length == 1 
     return array[0] 
     when array.length == 2 
     return array[0] + array[1]     
     when array.length.odd? && array.length >= 3     
     return array[(array.length - 1)/2] 
     when array.length.even? && array.length >= 4    
     return array[((array.length/2) - 1)] + array[(array.length/2)] 
     else nil 
     end 
end 



puts median("testing") 

was mit meinem Code ist falsch. Es läuft, liefert aber nichts. Jede Hilfe wird sehr geschätzt.

+1

Das Problem ist, Ihre (Fehl-) Nutzung von Fall/bei. Verwenden Sie stattdessen/elsif. Und lesen Sie, wo und für welchen Fall/wann _should_ verwendet werden sollte. –

+0

Ihre Case-Anweisung sollte 'case array.length' sein und die when-Anweisungen sollten' when 1' sein. –

+0

@TallPaul: Wie schlagen Sie vor, die letzten beiden Fälle dann zu behandeln? –

Antwort

1

Sie müssen array von der Linie case array entfernen. Ich habe nur diese Änderung an Ihren Code und es works just fine:

def median(string)       
    array = string.split(//) 
    case 
    when array.length == 1 
    return array[0] 
    when array.length == 2 
    return array[0] + array[1]     
    when array.length.odd? && array.length >= 3     
    return array[(array.length - 1)/2] 
    when array.length.even? && array.length >= 4    
    return array[((array.length/2) - 1)] + array[(array.length/2)] 
    else nil 
    end 
end 

In der ersten Version des Codes, mit case array, dass Ruby vergleichen würde auf jedem Zweig sollte den „wenn“ Wert (das ist immer ein boolean value) to array, das ist nie boolean, also nie gleich einem der Zweige. Aus diesem Grund war der Zweig else nil immer der Ausgangspunkt des Blocks case.

Wenn Sie case array in case ändern, wird Ruby mitgeteilt, dass kein Vergleich durchgeführt werden muss, sondern jede Verzweigungsbedingung ausgewertet und die erste ausgeführt werden muss, die wahr ist.


Nachdem dies gesagt ist, können Sie den Code in ein paar Möglichkeiten vereinfacht werden:

  • gibt es keine Notwendigkeit, den String in ein Array zu konvertieren; String Indizierung würde in diesem Fall gut funktionieren
  • die Bedingungen && array.length >= 3 und && array.length >= 4 sind überflüssig; ein niedrigerer Wert würde die oder array.length == 2 Zweige
  • treffen die oder array.length == 2 Zweige sind wirklich nicht so speziell; Sie können sie nur in den Fällen mit ungerader/gerader Länge behandeln.

diese Überlegungen Anwendung ich mit diesem Code am Ende, die auch works OK:

def word_median(word) 
    half = word.length/2 

    case 
    when word == '' then '' 
    when word.length.odd? then word[half] 
    else word[half - 1..half] 
    end 
end 
+0

"oder array.length == 2 Zweige sind wirklich nicht so speziell" - dieser Aufzählungspunkt widerspricht dem vorherigen. :) –

+0

danke Wolf, du bist dort über Bord gegangen. Ich habe die von dir durchgeführten Tests heruntergeladen.Ich hatte keine Ahnung, dass ich einen Index auf beide Werte verteilen konnte, umso erstaunlicher, dass ich diese Methoden auf eine Zeichenfolge anwenden konnte! Der Code sieht jetzt schlanker aus, genau wie es sein sollte, verfeinert bis zum Feinsten. – godhar