我需要转换此数组:
[:a, :b, :c, :d, :e]
进入此哈希:
{:a=>{:b=>{:c=>{:d=>:e}}}}
不幸的是,我缺少大脑的递归叶。我发现BottomlessHash
# http://firedev.com/posts/2015/bottomless-ruby-hash/
class BottomlessHash < Hash
def initialize
super &-> h, k { h[k] = self.class.new }
end
end
虽然我一直在努力理解“ pretzel stab”,但是如果您将其明确写出,它会成功解决问题,
bhash = BottomlessHash.new
bhash[:a][:b][:c][:d] = :e
bhash # => {:a=>{:b=>{:c=>{:d=>:e}}}}
但是我找不到一种以编程方式传递任意值的方法。
store
无效,send("[:a][:b][:c][:d]=", :e)
答案 0 :(得分:3)
send
的作用是调用 a 方法,该方法只有一个,带有零个或多个参数。它不能一次调用多个方法。您的示例在这里:
send("[:a][:b][:c][:d]=", :e)
这正试图调用一个名为[:a][:b][:b][:d]=
的方法,该方法实际上不存在,因此send
失败。
现在这是实际的Ruby代码:
x[:a][:b][:c][:d] = :e
被Ruby解释为:
x.send(:[], :a).send(:[], :b).send(:[], :c).send(:[]=, :d, :e)
做原始代码所做的只是一个很长的丑陋方法。这里的关键是每个[...]
部分都代表一个方法调用,该方法调用返回某个内容,然后对下一个部分进行评估,或者链接在上。
现在是该椒盐脆饼刺的原始部分:
super &-> h, k { h[k] = self.class.new }
&
的意思是“通过此Proc作为块参数传递”,如带有签名的方法一样:
initialize(&block)
&block
代表该方法的块(如果已给出),如:
Hash.new { |h,k| h[k] = { } }
在更基本的实现中。
-> h, k { ... }
部分传统上写为:
lambda { |h, k| ... }
那可能更容易识别。
答案 1 :(得分:2)
[:a, :b, :c, :d, :e].reverse_each.inject{|h, k| {k => h}}
# => {:a=>{:b=>{:c=>{:d=>:e}}}}
答案 2 :(得分:1)
ID Name Amount Comments
1 n1 421762 Hello
2 n2 5810 Bye
答案 3 :(得分:1)
array = [*:a..:e]
array[0..-2].reverse.reduce(array[-1]) { |b, a| { a => b } }
# {:a=>{:b=>{:c=>{:d=>:e}}}}