这两个代码有什么区别?遍历一个字符串并计算字母出现的次数并将其添加到我的哈希值中



>我正在尝试循环访问一个字符串:

statement = "The Game of Throne Rocks!"

用字母作为我的哈希值的键。我的键的值将是字母在我的字符串中出现的次数。

我通过堆栈溢出找到了这段代码:

statement.each_char do |char|
  next if char == " "
  result[char] = 0 unless statement.include?(char)
  result[char] += 1
end

有效,我试图重写它以达到我的理解。我下面的代码不起作用:

result = {}
statement.each_char do |char|
  if char == ' '
    next
  elsif result.include?(char)
    result[char] += 1
  else
    result[char] = 0
  end
end

请帮忙。

原始代码示例无条件执行 result[char] += 1 ,而您的代码示例仅在第二次看到字母时执行此操作。

也可以通过将哈希条目初始化为 1 来修复代码。

每次输入一个新字符时,您都会将其计数为零,而应将其设置为"一"。

此代码适用于您。

statement = "The Game of Throne Rocks!"
result = {}
statement.each_char do |char|
  if char == ' '
    next
  elsif result.include?(char)
    result[char] += 1
  else
    result[char] = 1
  end
end
result =>  {"T"=>2, "h"=>2, "e"=>3, "G"=>1, "a"=>1, "m"=>1, "o"=>3, "f"=>1, "r"=>1, "n"=>1, "R"=>1, "c"=>1, "k"=>1, "s"=>1, "!"=>1}
▶ statement = "The Game of Throne Rocks!"
#⇒ "The Game of Throne Rocks!"
▶ statement.downcase.delete(' ').split('').group_by(&:itself).map do |k, v|
▷   [k, v.size]
▷ end.to_h
#⇒ {"t"=>2, "h"=>2, "e"=>3, "g"=>1, "a"=>1, "m"=>1, "o"=>3,
#   "f"=>1, "r"=>2, "n"=>1, "c"=>1, "k"=>1, "s"=>1, "!"=>1}

一个很好的例子,展示了如何使用不同的解决方案解决相同的问题。

您的解决方案存在缺陷,因为即使字符出现过一次,您也会将计数器初始化为 0。如果修复此问题,那么它将按预期工作:

statement.each_char do |char|
  if char == ' '
    next
  elsif result.include?(char)
    result[char] += 1
  else
    result[char] = 1
  end
end

您可以使用injecteach-with_objcet来改进代码。像这样,你不需要在循环之前初始化哈希。我更喜欢each_with_object,因为您不需要像处理inject那样从块中返回累积对象。

count = statement.each_char.inject({}) do |hash, char|
  hash[char] = (hash[char] || 0) + 1 if char != ' '
  hash
end

count = statement.each_char.each_with_object({}) do |char, hash|
  hash[char] = (hash[char] || 0) + 1 if char != ' '
end

在这里,我们使用链接 http://ruby-doc.org/core-2.3.0/Enumerable.html 方法的可能性,因为它们在没有给出块时返回 en Enumerator

(hash[char] || 0) + 1 部分初始化计数器以在第一次出现时1,并防止nil + 1情况。你可以像这样写两行:

hash[char] = 0 if hash[char].nil?
hash[char] += 1

您可以通过使用初始化为0找不到的键的哈希来"简化"该部分。

count = statement.each_char.each_with_object(Hash.new(0)) do |char, hash|
  hash[char] += 1 if char != ' '
end

你也可以使用mudasobwa的解决方案,通过使用itself非常聪明。我只会将其更改为使用 each_char 而不是 split('')

statement.downcase.delete(' ').each_char.group_by(&:itself).map do |k, v|
  [k, v.size]
end.to_h

最新更新