我需要转换这个数组:
[:a,:b,:c,:d,:e]进入这个哈希:
{:A => {A:B => {:C => {:d =>:电子}}}}不幸的是,我错过了大脑的递归波瓣。我找到了BottomlessHash
#…
array = [*:a..:e] array[0..-2].reverse.reduce(array[-1]) { |b, a| { a => b } } # {:a=>{:b=>{:c=>{:d=>:e}}}}
items = [:a, :b, :c, :d, :e] # Iterative version def hashify(items) items = items.dup result = items.pop result = {items.pop => result} until items.empty? result end hashify(items) # => {:a=>{:b=>{:c=>{:d=>:e}}}} # Recursive version def hashify(items) return items.last if items.size < 2 *head, penultimate, last = items hashify(head + [{penultimate => last}]) end hashify(items) # => {:a=>{:b=>{:c=>{:d=>:e}}}}
[:a, :b, :c, :d, :e].reverse_each.inject{|h, k| {k => h}} # => {:a=>{:b=>{:c=>{:d=>:e}}}}
什么 send 打电话 一个 方法,只有一个,有零个或多个参数。它不能一次调用多个方法。你的例子在这里:
send
send("[:a][:b][:c][:d]=", :e)
这是试图调用一个名为的方法,字面意思, [:a][:b][:b][:d]= 哪个不存在,所以 send 失败。
[:a][:b][:b][:d]=
现在这个实际的Ruby代码:
x[:a][:b][:c][:d] = :e
被Ruby解释为:
x.send(:[], :a).send(:[], :b).send(:[], :c).send(:[]=, :d, :e)
这只是做原始代码所做的一种非常漫长,丑陋的方式。这里的关键是每个 [...] part表示一个返回某个东西的方法调用,然后根据该方法调用下一个部分,或者 被束缚住了 。
[...]
现在对于原始部分,这个椒盐卷饼刺:
super &-> h, k { h[k] = self.class.new }
该 & 表示“将此Proc作为块参数传递”,如同具有签名的方法一样:
&
initialize(&block)
哪里 &block 表示给定方法的块,如下所示:
&block
Hash.new { |h,k| h[k] = { } }
在更基本的实现中。
该 -> h, k { ... } 部分传统上写为:
-> h, k { ... }
lambda { |h, k| ... }
哪里可能更容易识别。