找不到以前的帖子来回答我的问题...我正在学习如何在 Ruby 中使用破坏性与非破坏性方法。我找到了我正在做的练习的答案(破坏性地向哈希值添加一个数字),但我想弄清楚为什么我的一些早期解决方案不起作用。这是有效的答案:

  def modify_a_hash(the_hash, number_to_add_to_each_value)
    the_hash.each { |k, v| the_hash[k] = v + number_to_add_to_each_value}
  end

这两个解决方案作为非破坏性返回(因为它们都使用“每个”,我不知道为什么。要使某些具有破坏性的是上面的等号可以解决问题吗?):
  def modify_a_hash(the_hash, number_to_add_to_each_value)
    the_hash.each_value { |v| v + number_to_add_to_each_value}
  end

  def modify_a_hash(the_hash, number_to_add_to_each_value)
    the_hash.each { |k, v| v + number_to_add_to_each_value}
  end

最佳答案

术语“破坏性”和“非破坏性”在这里有点误导。更好的是使用传统的“就地修改”与“返回副本”术语。

通常,就地修改的方法在其名称末尾有 ! 以用作警告,例如 gsub! 用于字符串。一些早于该约定的方法没有它们,例如 push for Array。
= 在循环内执行赋值。您的其他示例实际上并没有做任何有用的事情,因为 each 返回正在迭代的原始对象,而不管产生的任何结果。

如果你想返回一个副本,你可以这样做:

def modify_a_hash(the_hash, number_to_add)
  Hash[
    the_hash.collect do |k, v|
      [ k, v + number_to_add ]
    end
  ]
end

那将返回一个副本。内部操作 collect 将键值对转换为应用调整的新键值对。因为没有赋值,所以不需要 =

外部方法 Hash[] 将这些键值对转换为适当的 Hash 对象。然后返回并独立于原始文件。

通常,非破坏性或“返回副本”方法需要为它正在操作的事物创建一个新的、独立的版本,以便存储结果。这适用于字符串、数组、哈希或您可能正在使用的任何其他类或容器。

关于Ruby Hash 破坏性与非破坏性方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25854913/

10-11 16:21