无法找到回答我问题的上一篇文章...我正在学习如何在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
答案 0 :(得分:2)
条款"破坏性"和#34;非破坏性的"这里有点误导。更好的是使用传统的"就地修改" vs."返回副本"术语
通常,就地修改的方法在其名称末尾有!
作为警告,例如String的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对象。然后返回并独立于原始文件。
通常是非破坏性的,或者"返回副本"方法需要创建一个新的独立版本的东西,它为了存储结果而进行操作。这适用于String,Array,Hash或您可能正在使用的任何其他类或容器。
答案 1 :(得分:0)
也许这个略有不同的例子会有所帮助。
我们有一个哈希:
2.0.0-p481 :014 > hash
=> {1=>"ann", 2=>"mary", 3=>"silvia"}
然后我们迭代它并将所有字母更改为大写:
2.0.0-p481 :015 > hash.each { |key, value| value.upcase! }
=> {1=>"ANN", 2=>"MARY", 3=>"SILVIA"}
原始哈希已经改变,因为我们使用了大写!方法
比较没有的方法!符号,不会修改哈希值:
2.0.0-p481 :017 > hash.each { |key, value| value.downcase }
=> {1=>"ANN", 2=>"MARY", 3=>"SILVIA"}