2016-05-16 13 views
2

Ich arbeite an Anfänger Ruby Tutorials. Ich versuche eine Methode zu schreiben, die die Vokale zum nächsten Vokal bringt. 'a' wird 'e', ​​'e' wird 'ich', 'du wirst' 'werden' usw. usw. Ich habe schon eine ganze Weile lang verschiedene Ideen ausprobiert, ohne Erfolg.Advancing Vokal zum nächsten Vokal in Ruby

Ich denke, ich bin auf dem richtigen Weg, in dem ich ein Array der Vokale erstellen muss, und verwenden Sie dann einen Index, um sie zum nächsten Array im Vokal voranzubringen. Ich kann einfach nicht die richtige Methode dafür erstellen.

Ich weiß, das ist nicht bearbeitbare Code, aber meine Gliederung ist in diese Richtung. Wo ich in Probleme laufen wird meinen Code bekommt jeden Vokal zu erkennen und voraus in dem nächsten Vokal:

def vowel_adv(str) 
    vowels = ["a", "e", "i", "o", "u"] 

    str = str.split('') 
    **str_new = str.map do |letter| 
    if str_new.include?(letter) 
     str_new = str_new[+1] 
    end** 
    # The ** section is what I know I need to find working code with, but keep hitting a wall. 
    str_new.join 
end 

Jede Hilfe wäre sehr dankbar.

Antwort

4

Hier ist der Code mit den wenigsten Korrekturen notwendig, damit es funktioniert:

def vowel_adv(str) 
    vowels = ["a", "e", "i", "o", "u"] 
    str = str.split('') 
    str_new = str.map do |char| 
    if vowels.include?(char) 
     vowels.rotate(1)[vowels.index(char)] 
    else 
     char 
    end 
    end 
    str_new.join 
end 
vowel_adv "aeiou" 
=> "eioua" 

Dinge, die ich schließen geändert

  • Zugabe einer Blockgröße auf den map Block
  • das Ding Rückkehr Sie mappen von map Block
  • include? ist auf der 01 aufgerufen, nicht auf das mögliche Element
  • Den nächsten Vokal finden, indem Sie in das Array der Vokale schauen, nicht durch Inkrementieren des Charakters, was ich denke, Sie versuchten zu tun.

Hier ist eine verbesserte Version:

VOWELS = %w(a e i o u) 
ROTATED_VOWELS = VOWELS.rotate 1 

def vowel_adv(str) 
    str. 
    chars. 
    map do |char| 
     index = VOWELS.index char 
     if index 
     ROTATED_VOWELS[index] 
     else 
     char 
     end 
    end. 
    join 
end 
  • statische Array s in Konstanten
  • schönen Array-of-String-Syntax
  • String#chars statt split
  • den Index verwenden, um zu testen zur Aufnahme anstelle von include?
  • keine Zuordnung zu den Parametern, die ein wenig verwirrend
  • keine temporären Variablen ist, die einige Leute mögen und einige Leute nicht, aber ich hier getan haben, um zu zeigen, dass es

möglich ist, und nur, weil Ruby ist Spaß, hier ist eine andere Version der Zeichenkette, die Kopien und ändert die Kopie:

VOWELS = %w(a e i o u) 
ROTATED_VOWELS = VOWELS.rotate 1 

def vowel_adv(str) 
    new_str = str.dup 
    new_str.each_char.with_index do |char, i| 
    index = VOWELS.index char 
    if index 
     new_str[i] = ROTATED_VOWELS[index] 
    end 
    end 
    new_str 
end 
+0

Vielen Dank! Ich war noch nicht rotiert. Ich habe es gerade in Ruby Doc gesucht, es scheint genau die Methode zu sein, die ich brauchte. Dies führt genau das aus, was ich gesucht habe. – Orie

5

Weil wir nur ein paar Vokale haben, würde ich zuerst einen Hash enthält Vokaltasten und Vokal-Werte definieren:

vowels_hash = { 
    'a' => 'e', 
    'A' => 'E', 
    'e' => 'i', 
    'E' => 'I', 
    'i' => 'o', 
    'I' => 'O', 
    'o' => 'u', 
    'O' => 'U', 
    'u' => 'a', 
    'U' => 'A' 
} 

Dann würde ich über die Alphabete, die in jedem Wort/Satz wie so laufen:

word.split(//).map do |character| 
    vowels_hash[character] || character 
end.join 

Update:

BTW stattdessen das Wort Spaltung, auch gsub mit regex verwenden könnte + Hash Argumente wie folgt:

word.gsub(/[aeiouAEIOU]/, vowels_hash) 

Oder wie wenn Sie also Herr/Frau Fancy Pants sein wollen:

regex = /[#{vowels_hash.keys.join}]/ 
word.gsub(regex, vowels_hash) 
+0

Gute Arbeit Handhabung Großbuchstaben –

+2

danke @DaveSchweisguth. Ich stelle mir vor, wir könnten die 'rotate'-Methode verwenden, die Sie in Verbindung mit' zip' geteilt haben, um '' vowels_hash'' zu erzeugen, aber es ist viel klarer, es einfach in diesem Fall einzugeben. – Humza

+0

Dies ist eine großartige Lösung für Caps. Ich habe gerade .Downcase und .Capitalise, aber das hat viel größere Flexibilität als das, was ich tat – Orie

3

Die String-Klasse hat dafür eine nice method. Demo:

p "Oh, just a test".tr("aeiouAEIOU", "uaeioUAEIO") # => "Ih, jost u tast" 
+0

Beste bisher, imo. –

+0

Das ist wirklich cool @steenslag - wusste nicht über 'tr' – Humza

0

To Riff von steenslag's Antwort ein wenig.

VOWELS = %w{a e i o u A E I O U} 
SHIFTED_VOWELS = VOWELS.rotate 1 

def vowel_shifter input_string 
    input_string.tr!(VOWELS.join, SHIFTED_VOWELS.join) 
end 

und nur zum Spaß, Konsonanten:

CONSONANTS = ('a'..'z').to_a + ('A'..'Z').to_a - VOWELS 
SHIFTED_CONSONANTS = CONSONANTS.rotate 1 

def consonant_shifter input_string 
    input_string.tr!(CONSONANTS.join, SHIFTED_CONSONANTS.join) 
end 
Verwandte Themen