Reputation: 123
Here is a function to count in an if
statement the vowels contained in a string:
def count_vowels(string)
sum = 0
n = 0
while n < string.length
if string[n] == "a"||string[n]=="i"||string[n]=="u"||string[n]=="e"||string[n]=="o"
sum += 1
end
n+=1
end
return sum
end
I found the repetitive string[n] ==
being redundant and replaced it with:
if string[n] == ("a"||"i"||"u"||"e"||"o")
However, in this code, the function does not return the correct counts. Why does the simplified if
statement not work here?
Upvotes: 1
Views: 150
Reputation: 6263
To answer your question
string[n] == ("a"||"i"||"u"||"e"||"o")
This part ("a"||"i"||"u"||"e"||"o")
would always evaluate to "a"
so you are essentially writing
string[n] == "a"
A better way to do this might be
def count_vowels(my_string)
mystring.chars.count{ |c| c =~ /[aeiou]+/i }
end
You could also extend the string class for fun
class String
def vowels_count
chars.count{ |c| c =~ /[aeiou]+/i }
end
end
Upvotes: 2
Reputation: 44581
It doesn't return correct count because ||
in if string[n] == ("a"||"i"||"u"||"e"||"o")
evaluates to the first non-false condition, in this case, "a"
(it is not nil
or false
), so basically it is the same as if string[n] == "a"
.You can try with include?
:
%w( a i u e o).include? string[n]
or in?
:
string[n].in? %w( a i u e o)
Upvotes: 0
Reputation:
Your if
statement doesn't work because == ("a" || ...)
doesn't tell Ruby to check if it's equal to any of these. Instead, it evaluates ("a" || ...)
and checks if string[n]
is equal to that.
The "proper" simplified expression would be this:
string[n] =~ /aeiou/i
Assuming you want case-insensitivity, that is. If not, use this:
string[n] =~ /aeiou/
Note that with this solution you'll have to escape any regex metacharacters (.
, []
, ()
, etc.)
If you don't want to do that, use something like this instead:
['a', 'e', 'i', 'o', 'u'].include? string[n]
Upvotes: 0
Reputation: 114218
It doesn't work, because a == (x || y)
is not expanded to a == x || a == y
.
Instead, a
is compared against the result of (x || y)
.
if string[n] == ("a"||"i"||"u"||"e"||"o")
is equivalent to:
if string[n] == "a"
because:
("a"||"i"||"u"||"e"||"o") #=> "a"
If you want to simplify your code, use count
:
def count_vowels(string)
string.count('aeiou')
end
Upvotes: 4
Reputation: 34774
There are various ways you can do what you want but the reason it doesn't work is because ("a"||"e"||"i"||"o"||"u")
is evaluated by ruby to return the first of those characters that isn't false
or nil
. Essentially that clause always returns "a"
:
2.2.1 :001 > ("a"||"e"||"i"||"o"||"u")
=> "a"
This means that you are always testing if string[n] == "a"
which is clearly not what you are aiming to achieve.
Upvotes: 1
Reputation: 6100
Add regular expersion
def count_vowels(string)
sum = 0
n = 0
while n < string.length
if string[n] =~ /[aiueo]/ # will match a, i, u, e or o
sum += 1
end
n+=1
end
return sum
end
You can even more simplify your code
def count_vowels(string)
string.split('').select{|char| char =~ /[aeiou]/}.length
end
will do the same functionality
string.split('')
will give you array of characters
.select{|char| char =~ /[aeiou]/}
will select only 'a' 'e' 'i' 'o' 'u' characters
.length
will count number of those characters
Upvotes: 0