2014-08-27 28 views
1

我要评论的原始问题,但我还没有这样做的声誉呢......更新红宝石中的哈希值澄清

我也想知道如何轻松更新所有的值散列,或者是否有某种等效的.map!散列方法。有人把了这个优雅的解决方案:

hash.update(hash){|key,v1| expresion} 

在这个问题上: Ruby: What is the easiest method to update Hash values?

我的问题是如何块知道遍历哈希每个元素?例如,我不得不打电话。每一个散列来访问每个元素通常这样为什么不是这样的:

hash.update(hash.each) do |key ,value| 
    value+=1 
end 

与{块|键,值|表达式}我正在访问每个单独的散列元素,但我不必明确告诉系统呢?为什么不?非常感谢你。

回答

0

Hash#updateHash#merge!的别名,它更具描述性。

当调用与块的方法中,将发生以下情况(来自文档的摘录):

如果[A]为指定块,[...]的每个重复的键的值是 确定通过调用块与键[...]

所以,上面的代码是这样的:

哈希值合并本身,并为每个重复键块被调用。当我们将散列与自身合并时,每个新添加的键都是重复的,因此块被调用。结果是散列中的每个值都被替换为expresion

+0

'expresion'是对问题中原始代码的引用(它已经有一个错字)。 – koffeinfrei 2014-08-27 21:20:31

0

Hash#update将散列作为第一个参数,将可选块作为第二个参数。如果省略第二个参数,则该方法将在内部循环所提供散列中的每个键值对,并将它们合并到原始散列中。

如果提供了块(第二个参数),则该方法执行完全相同的操作。它循环遍历所提供的散列中的每个键值并将其合并。唯一的区别是发现冲突的位置(原始散列已经具有特定键的条目)。在这种情况下,该块被调用来帮助解决冲突。

基于这种理解,仅仅将散列传递给自身会导致它循环遍历每个键值,因为这就是update总是如何工作的。调用.each将是多余的。

要更清楚地了解这一点,请查看#update方法的源代码,并注意在任一逻辑分支中内部调用rb_hash_foreach

+0

因此,在发生冲突(重复键)的情况下,块是原始哈希更新的规则?所以你可以说像{| key,value} value + = 1}之类的东西?您能否创建一个碰撞规则,以便您使用原始哈希值和第二个哈希值的平均值更新原始哈希值?试图了解这种方法的范围。非常感谢您的回复。 – HectorOfTroy407 2014-08-27 20:54:11

+0

如果您检查文档,您会看到块arity实际上接受3个参数:碰撞键,原始值和新值。所以是的,考虑到第二和第三个参数的平均值会给你结果:'{| key,v1,v2 | (v1 + v2)/ 2}' – PinnyM 2014-08-28 13:06:19