ruby - 当我只有值时如何在哈希中返回键?
问题描述
显而易见的答案(至少在我看来)是使用 .key(value) 但是我不断收到错误“未定义的键方法”。我必须返回最高值的第一个实例的键。这是我输入的;
def high(x)
alphabet = Hash.new(0)
count = 0
("a".."z").each do |char|
alphabet[char] = count += 1
end
words = Hash.new(0)
x.split(" ").each do |word|
count_a = 0
word.each_char do |chars|
if alphabet.has_key?(chars)
count_a += alphabet[chars]
end
end
words[word] = count_a
end
highest = words.sort_by { |key, value| value }
(highest[0][1]..highest[-1][1]).each do |val|
if val == highest[-1][1]
return highest.key(val)
else
return highest[-1][0]
end
end
end
我知道这是乱七八糟的代码(我只有几个月的时间学习编码)。我面临的问题具体在以下部分;
highest = words.sort_by { |key, value| value }
(highest[0][1]..highest[-1][1]).each do |val|
if val == highest[-1][1]
return highest.key(val)
else
return highest[-1][0]
end
end
所以在我写'returnhighest.key(val)'的地方,我希望它返回等于最高'得分'单词的单词,但是它只是给了我未定义的方法错误。任何帮助将不胜感激。
解决方案
使用可枚举和字符串方法使魔术发生
我很高兴你已经回答了你自己的问题。同时,如果您不关心跟踪所有单词,或者保留每个单词得分的运行列表,那么您可以通过让 Ruby 做更多事情来使这变得更简单、更快、内存更少为您完成的工作,只返回得分最高的项目。
Ruby 有很多内置的方法可以让这样的工作变得更容易,而且它的核心方法通常是高度优化的。这是一个包含七行代码(不包括注释)的解决方案,它利用 Array 继承的Enumerable#zip、Enumerable#sum和Enumerable#max_by方法来完成大部分繁重的工作。
Hash#merge帮助我们处理一些极端情况,例如复合词中的空格或破折号。然后,在String#chars和String#downcase 的帮助下!,这几乎就像 Ruby 为我们做的一样!
在 Ruby 3.0.2 中:
# Map your numerical score to each letter and store in a Hash.
#
# @note We can prepend a value of zero for spaces and other special
# characters, too!
ALPHA_SCORES = {" " => 0, "-" => 0}.merge (?a..?z).zip(1..26).to_h
# Convert all words to lowercase, and return the highest-scoring word
# and its score as an Array.
def find_highest_scoring_word_in *words
words.flatten.map do |word|
word.downcase!
[word, word.chars.sum { ALPHA_SCORES[_1] }]
end.max_by(&:last)
end
这种方法提供了很大的灵活性。例如,您可以通过以下所有方式调用它,它会返回正确的结果。
# pass a single Array of String objects
find_highest_scoring_word_in %w[foo bar baz]
#=> ["foo", 36]
# pass two Array of String arguments
find_highest_scoring_word_in %w[foo bar baz], %w[quux wuuble]
#=> ["wuuble", 84]
# pass in three separate String arguments
find_highest_scoring_word_in 'alpha', 'beta', 'gamma'
#=> ["alpha", 38]
# Pass in expressions that evaluate to a String. The first creates 100
# letter a's, and the second 4 z's. Since `z` is worth 26 points, and
# `a` only 1, it's "zzzz" for the win!
find_highest_scoring_word_in 'a' * 100, 'z' * 4
#=> ["zzzz", 104]
推荐阅读
- python - 实例作为属性
- python - 如何将 MonthYear 字符串转换为 Datetime Pandas?
- c# - datagridview fullrowselect 但为什么列仍然选择和突出显示?.net5
- ffmpeg - 如何使多个文件输入命令在 ffmpeg fluent 中工作
- latex - 如何在乳胶中为参考括号着色?我尝试过的所有方法都与 biblatex 不兼容,所以我得到的参考输出为 [?]
- mysql - 数据库连接不起作用(另一个服务器中的数据库,discord.js)
- ruby-on-rails - 如何将 raw_filter 方法添加到 ruby on rails 7?
- python - 熊猫水平折叠数据框
- mysql - 填写缺少的日期 mySQL
- unix - 跨多个 Unix 服务器管理用户和组