patternrubyMinor
Yet another vowel counting program
Viewed 0 times
countingprogramyetanothervowel
Problem
Several months ago, I asked Program to count vowels, which was asking for a code review of a vowel counting function in implemented in Python.
Since I've been trying to learn Ruby, I decided to reimplement the entire program in it. I'm mainly looking for critiques on:
Of course there are some slight changes in how I implemented this in ruby vs Python. The biggest being simply using a
Since I've been trying to learn Ruby, I decided to reimplement the entire program in it. I'm mainly looking for critiques on:
- Naming conventions
- Best practices for string iteration
do/endvs{}
- Coding standards and best practices
Of course there are some slight changes in how I implemented this in ruby vs Python. The biggest being simply using a
Hash since I couldn't find a suitable replacement for Python's tuples. On a unrelated side note, is there a replacement for Python's tuples in ruby?def count_vowels(string)
# Create a function that will receive a string. The
# function will count each vowel in the string and
# return a count of all the vowels, whether found or not,
# each being a `key, value` in a Hash.
vowels = {"a" => 0, "e" => 0, "i" => 0, "o" => 0, "u" => 0}
string.each_char do |chr|
if vowels.has_key?(chr)
vowels[chr] += 1
end
end
return vowels
endSolution
You could use
You very rarely need to declare a variable (
So while calling
Same idea, just written out in separate filter/count steps.
You can also skip the
I'd also use a plain array for the vowels. Looking up hash keys is faster, sure, but does it really matter that much? Nah. "Premature optimization is the root of all evil" and all that.
and then the block becomes:
If you keep the vowels array sorted, you can use
Of course you could also do something funky like this: Remove all the vowels and see how much shorter the string is afterward:
This is also easily made case-insensitive:
Or instead of
(or
Alternatively, you could extend/monkey-patch the
The
Again, this is mostly for fun. I just thought it made the
Enumerable#count:string.chars.count { |char| vowels.has_key?(char) }You very rarely need to declare a variable (
i in this case), and then modify it form inside a block; there's almost always a better way in Ruby.So while calling
count and passing a block is the most direct, you could also have done something like:string.chars.select { |char| vowels.has_key?(char) }.countSame idea, just written out in separate filter/count steps.
You can also skip the
return since that's implied at the end of a method.I'd also use a plain array for the vowels. Looking up hash keys is faster, sure, but does it really matter that much? Nah. "Premature optimization is the root of all evil" and all that.
vowels = %w(a e i o u) # same as ["a", "e", "i", ...]and then the block becomes:
vowels.include?(char)If you keep the vowels array sorted, you can use
bsearch if you want to speed it up a little. Or you can construct the hash in code, instead of typing all that => 0:list = %w(a e i o u)
vowels = Hash[list.zip(list)] # => { "a" => "a", "e" => "e", ... }Of course you could also do something funky like this: Remove all the vowels and see how much shorter the string is afterward:
def count_vowels(string)
string.length - string.gsub(/[aeiou]/, '').length
endThis is also easily made case-insensitive:
string.length - string.gsub(/[aeiou]/i, '').lengthOr instead of
gsub you can use tr:string.length - string.tr('aeiou', '').length(or
'aeiouAEIOU' for case-insensitivity.)Alternatively, you could extend/monkey-patch the
String class a little. I wouldn't recommend it for production code, though. This is just illustrate some Ruby features:class String
def vowel?
self =~ /\A[aeiou]\z/ ? true : false
end
end
def count_vowels(string)
string.chars.count(&:vowel?)
endThe
&x syntax is a shorthand meaning "invoke x on each element in the collection", so it's equivalent to { |e| e.x }.Again, this is mostly for fun. I just thought it made the
count_vowels method nice and short. And of course, count_vowels could itself be monkey-patched onto String, so you could just call some_string.count_vowels. But again, monkey-patching - while fun - shouldn't be the first thing you reach for. Just illustrating the principle.Code Snippets
string.chars.count { |char| vowels.has_key?(char) }string.chars.select { |char| vowels.has_key?(char) }.countvowels = %w(a e i o u) # same as ["a", "e", "i", ...]vowels.include?(char)list = %w(a e i o u)
vowels = Hash[list.zip(list)] # => { "a" => "a", "e" => "e", ... }Context
StackExchange Code Review Q#151832, answer score: 7
Revisions (0)
No revisions yet.