目标是从['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]}
# => {}
这是为什么?知道如何在优雅的单线中实现理想的效果吗?
答案 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的解决方案更好,因为它更清楚正在发生什么。在注入中改变累加器通常会让人感到困惑,而且比它的价值更麻烦。