Ruby注入递归?

时间:2011-02-15 07:22:21

标签: ruby recursion

目标是从['a','b','c']开始,最后以{'a'=>{'b'=>{'c'=>{}}}}

结束

所以,得到我的支持,我这样做了:

['a','b','c'].inject({}){|h,v| h.update(v => {})}
# => {"a"=>{}, "b"=>{}, "c"=>{}} 

然后想一想,如果我实际传递结果哈希,它将递归并嵌套,但是:

['a','b','c'].inject({}){|h,v| h.update(v => {}); h[v]}
# => {} 

这是为什么?知道如何在优雅的单线中实现理想的效果吗?

2 个答案:

答案 0 :(得分:12)

['a','b','c'].reverse.inject({}) {|r,v| {v=>r}}

或换句话说:

构造一个散列,其中键是第一个数组元素(反转后为'c'),种子(空散列)作为值。在每个步骤中构造一个新的哈希,其中键是数组中的下一个值,值是从上一步返回的哈希值。

以下是每次注入迭代后的结果:

r={}, v='c'返回{'c'=>{}}

r={'c'=>{}}, v='b'返回{'b'=>{'c'=>{}}}

r={'b'=>{'c'=>{}}}, v='a'返回{'a'=>{'b'=>{'c'=>{}}}}

答案 1 :(得分:5)

Zetetic已经为您提供了一个有效的解决方案,但这就是为什么您的工作不起作用的原因:

['a','b','c'].inject({}){|h,v| h.update(v => {}); h[v]}

这确实会创建哈希{'a'=>{'b'=>{'c'=>{}}}}但是,inject不会返回该哈希值,它会返回最后一次调用块的结果,并且{}因为h 1}}将是为最后一个元素创建的哈希,即{'c' => {}},因此h[v]将为{}

要查看您想要的哈希实际上是否已创建,只是未返回,您可以先将传入的哈希存储在变量中,如下所示:

hash = {}
['a','b','c'].inject(hash){|h,v| h.update(v => {}); h[v]}

这样inject仍将返回{},但hash现在将包含哈希{'a'=>{'b'=>{'c'=>{}}}}。据说zetetic的解决方案更好,因为它更清楚正在发生什么。在注入中改变累加器通常会让人感到困惑,而且比它的价值更麻烦。