代码
def partition_hash(hash)
hash.each_with_object({}) do |(k,v), h|
key = k[/(?<=_).+(?=_)/]
h[key] = (h[key] || {}).merge(k=>v)
end.values
end
示例
hash = {"a_1_a"=>"1", "a_1_b"=>"2", "a_1_c"=>"3", "a_2_a"=>"3", "a_2_b"=>"4", "a_2_c"=>"4"}
partition_hash(hash)
#=> [{"a_1_a"=>"1", "a_1_b"=>"2", "a_1_c"=>"3"},
# {"a_2_a"=>"3", "a_2_b"=>"4", "a_2_c"=>"4"}]
说明
步骤如下。
enum = hash.each_with_object({})
#=> #<Enumerator: {"a_1_a"=>"1", "a_1_b"=>"2", "a_1_c"=>"3", "a_2_a"=>"3",
# "a_2_b"=>"4", "a_2_c"=>"4"}:each_with_object({})>
生成此枚举器的第一个元素并将其传递给块,并使用并行赋值计算块变量。
(k,v), h = enum.next
#=> [["a_1_a", "1"], {}]
k #=> "a_1_a"
v #=> "1"
h #=> {}
并执行块计算。
key = k[/(?<=_).+(?=_)/]
#=> "1"
h[key] = (h[key] || {}).merge(k=>v)
#=> h["1"] = (h["1"] || {}).merge("a_1_a"=>"1")
#=> h["1"] = (nil || {}).merge("a_1_a"=>"1")
#=> h["1"] = {}.merge("a_1_a"=>"1")
#=> h["1"] = {"a_1_a"=>"1"}
现在
h #=> {"1"=>{"a_1_a"=>"1"}}
现在生成enum 的下一个值并将其传递给块,并执行以下计算。
(k,v), h = enum.next
#=> [["a_1_b", "2"], {"1"=>{"a_1_a"=>"1"}}]
k #=> "a_1_b"
v #=> "2"
h #=> {"1"=>{"a_1_a"=>"1"}}
key = k[/(?<=_).+(?=_)/]
#=> "1"
h[key] = (h[key] || {}).merge(k=>v)
#=> h["1"] = (h["1"] || {}).merge("a_1_b"=>"2")
#=> h["1"] = ({"a_1_a"=>"1"}} || {}).merge("a_1_b"=>"2")
#=> h["1"] = {"a_1_a"=>"1"}}.merge("a_1_b"=>"2")
#=> h["1"] = {"a_1_a"=>"1", "a_1_b"=>"2"}
在enum 的其余四个元素被传递到块后,返回下面的has。
h #=> {"1"=>{"a_1_a"=>"1", "a_1_b"=>"2", "a_1_c"=>"3"},
# "2"=>{"a_2_a"=>"3", "a_2_b"=>"4", "a_2_c"=>"4"}}
最后一步就是提取值。
h.values
#=> [{"a_1_a"=>"1", "a_1_b"=>"2", "a_1_c"=>"3"},
# {"a_2_a"=>"3", "a_2_b"=>"4", "a_2_c"=>"4"}]