John
John

Reputation: 3

Ruby taking the last vowel from a word problem

I've been stressing out a lot about a problem I feel like I should be getting but don't know why it's not working.

Basically a method that takes a word and returns a word without the last vowel.

My code was:

def lastvowel(word)
    vowels = "aeiou"

    if vowels.include? (word)
        word.reverse.sub(/[aeiou]/, "").reverse
    else
        return word 
    end


end

the problem was that the vowels.include? (word) was not working? but I feel like it should be working? Maybe I'm thinking something else. So instead I made it like this:

def lastvowel(word)
    vowel = "aeiou"

    word.each_char do |x|
        if vowel.include?(x) 
        return word.reverse.sub(/[aeiou]/, "").reverse
        end
    end
return word

end

Is my understanding of the .include? method not correct? Any help would be very appreciated, thank you in advance.

Upvotes: 0

Views: 186

Answers (3)

builder-7000
builder-7000

Reputation: 7627

You could define String#lastvowel:

class String
  def lastvowel
    sub(/(.*)[aeiou](.*)/,'\1\2')
  end
end

and use like this:

"something".lastvowel
=> "somethng"

Upvotes: 3

Cary Swoveland
Cary Swoveland

Reputation: 110685

"problematic".sub(/[aeiou](?=[^aeiou]*\z)/i, '')
  #=> "problematc"

"HELLO".sub(/[aeiou](?=[^aeiou]*\z)/i, '')
  #=> "HELL"

"sly".sub(/[aeiou](?=[^aeiou]*\z)/i, '')
  #=> "sly"

See String#sub.

The regular expression reads, "match any vowel ([aeiou]) followed by zero or more (*) characters other than vowels ([^aeiou]), followed by the end of the string (\z), the matches being case indifferent (/i)".

[aeiou] is a character class, meaning exactly one of its contents is to be matched.

(?=[^aeiou]*\z) is a positive lookahead (signified by ?=).

[^aeiou] is also a character class, but the carat (^) in the first position means that exactly one character other than the characters that follow ^ is to be matched. Here that means a consonant.

Another way is to use the method String#rindex:

str = "problematic"
idx = str.rindex(/[aeiou]/i)
idx ? (str[0,idx]+str[idx+1..-1]) : str
  #=> "problematc"

str = "A"
idx = str.rindex(/[aeiou]/i)
idx ? (str[0,idx]+str[idx+1..-1]) : str
  #=> ""

Upvotes: 1

Amadan
Amadan

Reputation: 198344

vowels.include? (word) would test e.g. if the word is found in the string "aeiou". First of all, you likely wanted to test the reverse, whether vowels are in the word, not if the word is in the vowels; secondly, no word in English language has "aeiou" as its substring (the closest AFAIK are "leguleious", "epigaeous", "glutaeous" and "paeounlae", with one of the vowels missing).

What you want is to know if any of the vowels is included in the word; the shortest way to write that is vowels.any? { |vowel| word.include?(vowel) }. The check is not really necessary, if there are no vowels in the word you'd just be doing some unnecessary reversals.

Finally, you can do everything in just one sub, without reversals, and no tests:

word.sub(/[aeiou](?!.*?[aeiou])/, "")

("a vowel not followed by stuff and another vowel")

Upvotes: 2

Related Questions