第一次学习Ruby并尝试使用它来学习如何使用它进行功能编程,在我明确想要对其进行更改之前,不要对对象进行更改(使用!
)
text = "foo bar baz baz baz Foo FOO foo"
# Splitting the sentence into an array of words
words = text.downcase.split(" ")
# Hash to store the frequencies of each word
frequencies = Hash.new(0)
# Count the instances of a word one by one
words.each { |word| frequencies[word] += 1 }
# Sort it by the most frequent words
frequencies.sort_by { |word, count| count}.reverse!
# Print out the histogram
frequencies.each { |word, count| puts "#{word} #{count}"}
打印出以下
foo 4
bar 1
baz 3
预期结果将是
foo 4
baz 3
bar 1
我知道这可以解决
frequencies = frequencies.sort_by { |word, count| count}.reverse!
但是我喜欢ruby中简单的!
重新分配语法,并且想知道是否可以避免使用此frequencies =
吗?
执行frequencies.sort_by! { |word, count| count}.reverse!
会引发undefined method
错误。
我还发现工作解决方案有点违反直觉,因为它首先解决了
frequencies.sort_by { |word, count| count}
然后将其分配给 frequencies =
,然后调用下一个方法.reverse!
我现在认为了解如何阅读有效的解决方案。
frequencies.sort_by { |word, count| count}
返回一个新的哈希,然后由reverse
反转。
!
不执行任何操作,因为它“重新分配”了没有变量分配的新的(经过排序和反转的)哈希。
然后将整个内容分配给frequencies
答案 0 :(得分:4)
您似乎只是在进行命令式编程,因为我主要看到的是语句列表。 我建议您将逻辑包装在函数中,以便可以清楚地定义要处理的输入和输出:
def word_frequencies(text)
words = text.downcase.split(" ")
frequencies = Hash.new(0)
words.each { |word| frequencies[word] += 1 }
frequencies.sort_by { |word, count| count}.reverse
end
这样,您可以清楚地说明:
一旦您清楚地定义了函数的边界,执行分配就不会感到羞耻。
有些时候您需要产生副作用,例如在屏幕上打印一些东西:
frequencies = word_frequencies("foo bar baz baz baz Foo FOO foo")
frequencies.each { |word, count| puts "#{word} #{count}"}
最后,如果您要尝试使用完全链接的程序,可以使用Object#then
:
"foo bar baz baz baz Foo FOO foo".then do |text|
text.downcase.split(" ")
end.then do |words|
words.each_with_object(Hash.new(0)) do |word, memo|
memo[word] += 1
end
end.then do |frequencies|
frequencies.
sort_by { |word, count| count}.
reverse
end.each do |word, count|
puts "#{word} #{count}"
end
# foo 4
# baz 3
# bar 1
选择你的毒药。 :-)