Другой ответ правильно объясняет, почему это не работает так, как ожидалось.Позвольте мне попытаться указать на еще некоторые проблемы с вашим кодом:
string.downcase!
изменяет аргумент, переданный функции, что является очень плохим стилем /(\b\w+\b)/
Вы не делаетеЗдесь не нужна дополнительная группа совпадений, просто используйте /\b\w+\b/
.Это позволит вам просто использовать scan(...) do |x|
, где x
будет совпавшим словом wordhash.store(x,y)
можно просто записать как wordhash[x] = y
string.scan(/\b#{x}\b/).length
вы сканируете строкуво второй раз, хотя это не обязательно.Вместо этого вы можете просто увеличить счетчик для каждого совпадения данного слова.
Пример:
def count_words(string)
# set up a hash that accumulates the number of occurrences per word
wordcount = Hash.new(0)
string.downcase.scan(/\b\w+\b/) { |word| wordcount[word] += 1 }
# no need to use return here, the function already evaluates to the last
# value
wordcount
end
p count_words("Hello there. This is bob bob bob")
# => {"hello"=>1, "there"=>1, "this"=>1, "is"=>1, "bob"=>3}
Это просто для демонстрации того, как ваш подход может быть реализован вRuby, вы, вероятно, решили бы это более функциональным способом, предпочтительно используя group_by
, как уже продемонстрировал Майкл, или inject
:
string.downcase.split.inject(Hash.new(0)) { |h,word| h[word] += 1; h }