我需要使用 a 中的排序键将散列 a 的值合并到 out 。
a = {"X"=>{12=>1, 11=>4}, "Y"=>{11=>5}, "Z"=>{12=>5}}
out = [
{"X": [4, 1]},
{"Y": [5, 0]},
{"Z": [0, 5]},
]
答案 0 :(得分:2)
我会做这样的事情:
a = {"X"=>{12=>1, 11=>4}, "Y"=>{11=>5}, "Z"=>{12=>5}}
sorted_keys = a.values.flat_map(&:keys).uniq.sort
#=> [11, 12]
a.map { |k, v| { k => v.values_at(*sorted_keys).map(&:to_i) } }
#=> [ { "X" => [4, 1] }, { "Y" => [5, 0] }, { "Z" => [0, 5] }]
答案 1 :(得分:1)
<强>代码强>
def modify_values(g)
sorted_keys = g.reduce([]) {|arr,(_,v)| arr | v.keys}.sort
g.each_with_object({}) {|(k,v),h| h[k] = Hash.new(0).merge(v).values_at(*sorted_keys)}
end
示例强>
g = {"X"=>{12=>1, 11=>4}, "Y"=>{11=>5}, "Z"=>{12=>5}}
modify_values(g)
#=> {"X"=>[4, 1], "Y"=>[5, 0], "Z"=>[0, 5]}
<强>解释强>
步骤如下(对于示例中的散列a
)。首先从g
的值中获取唯一键的数组(请参阅Enumerable#reduce和Array#|),然后对该数组进行排序。
b = a.reduce([]) {|arr,(_,v)| arr | v.keys}
#=> [12, 11]
sorted_keys = b.sort
#=> [11, 12]
a
的第一个键值对与空哈希一起传递给each_with_object
块。块变量使用并行赋值计算:
(k,v),h = [["X", {12=>1, 11=>4}], {}]
k #=> "X"
v #=> {12=>1, 11=>4}
h #=> {}
然后执行块计算。首先创建一个带有默认值 0
的空哈希:
f = Hash.new(0)
#=> {}
哈希v
然后合并到f
。结果是哈希,其键值对与v
相同,但默认值为0
。默认值的重要性在于,如果f
没有键k
,则f[k]
会返回默认值。请参阅Hash::new。
g = f.merge(v)
#=> {12=>1, 11=>4}
g.default
#=> 0 (yup)
然后提取与sorted_keys
对应的值:
h[k] = g.values_at(*sorted_keys)
#=> {12=>1, 11=>4}.values_at(11, 12)
#=> [4, 1]
当a
的下一个键值对传递给块时,计算如下:
(k,v),h = [["Y", {11=>5}], {"X"=>[4, 1]}] # Note `h` has been updated
k #=> "Y"
v #=> {11=>5}
h #=> {"X"=>[4, 1]}
f = Hash.new(0)
#=> {}
g = f.merge(v)
#=> {11=>5}
h[k] = g.values_at(*sorted_keys)
#=> {11=>5}.values_at(11, 12)
#=> [5, 0] (Note h[12] equals h's default value)
现在
h #=> {"X"=>[4, 1], "Y"=>[5, 0]}
a
的第三个键值对的计算类似。