Reputation: 2333
CoderByte offers the following challenge: "Using the Ruby language, have the function WordCount(str) take the str string parameter being passed and return the number of words the string contains (ie. "Never eat shredded wheat" would return 4). Words will be separated by single spaces."
I solved it, but is there a simpler solution (that doesn't use regular expressions or methods other than .length)? I have a conditional inside of a conditional inside of a for-loop inside of a for-loop. I also set the current variable to false both inside and outside the first for-loop.
Are these poor practices? Is there a better solution?
def WordCount(string)
alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
counter = 0
current = false
for i in 0...string.length
prev = current
current = false
for j in 0...alphabet.length
if string[i] == alphabet[j]
current = true
if prev == false
counter += 1
end
end
end
end
return counter
end
WordCount(STDIN.gets)
Upvotes: 3
Views: 6918
Reputation: 110675
Punctuation is obviously an issue. Aside from the apostrophe, mentioned elsewhere, old-schoolers hyphenate certain groups of words, such as compound adjectives, dashes are used to set off clauses, ellipses (e.g., the symbol ' …' or multiple periods) indicate continuation or a change of thought, slashes provide choices and so on. One way to deal with that (without using a regrex) would be to first use String#tr (or String#gsub) to convert those punctuation characters to spaces (remove '
if you want "don't" treated as one word):
def word_count str
str.tr("'-/–…\.", ' ').split.size
end
word_count "It was the best of times, it was the worst of times"
#=> 12
word_count "I don't think his/her answer is best."
#=> 9
word_count "Mozart is a much-beloved composer." # with hyphen
#=> 6
word_count "I pay the bills–she has all the fun." # with dash
#=> 9
word_count "I wish you would…oh, forget it." # with ellipse
#=> 7
word_count "I wish you would––oh, forget it." # with dashes
#=> 7
word_count ""
#=> 0
On a Mac, a dash is entered as Option, hyphen; an ellipse, Option, semi-colon (or "semicolon", both are accepted :-) ).
Now we just have to figure out how to count hyphenated words ("state-of-the-art") as a single word. Actually, I've just scratched the surface of this complex subject. Sorry if I got carried away. What was the question again?
Upvotes: 1
Reputation: 1939
string = '' => Your string will be stored in this variable
word_count = string.split(' ').count
This should solve it.
Upvotes: 0
Reputation: 33626
It does involve regular expressions but it's the correct solution:
"Hi there 334".scan(/[[:alpha:]]+/).count # => 2
Upvotes: 6
Reputation: 8424
The most elegant solution I've seen on finding word count in Ruby was:
words = 'This is a word'
p words.scan(/\S+/).size #=> 4
For most convenience, monkey patch String:
class String
def number_of_words
self.scan(/\S+/).size
end
end
p 'Hi there, how are you?'.number_of_words #=> 5
The main problem I see with your code is that you're coding, but you aren't coding in Ruby(style). You'll rarely see people use for/in here, for example. If you know how to write idiomatic Ruby, code that would take 10 lines in other languages are barely 1 line long here.
Upvotes: 1
Reputation: 15781
Hm,
s = "Never eat shredded wheat"
puts s.split.count
# => 4
If you don't want to count underscores and digits:
s = "Never eat shredded wheat 1 _ ?"
puts s.split.reject { |w| w =~ /(\W|_|\d)/ }.count
# => 4
even more advanced regexp:
s = "Never __ 111 ?? eat shredded wheat. _Word?"
p s.split.reject { |w| w !~ /([a-zA-Z]+(_[a-zA-Z]+)*)/ }
# => ["Never", "eat", "shredded", "wheat.", "_Word?"]
Upvotes: 4