通过第一个哈希构造ruby多维哈希
我的散列如下:通过第一个哈希构造ruby多维哈希,ruby,arrays,data-structures,hash,Ruby,Arrays,Data Structures,Hash,我的散列如下: mm = { 0 => { 0 => 'p1', 1 => 'p2', 2 => 'p3' }, 1 => { 0 => 'idfp1', 1 => 'idfp2', 2 => 'idfp3' }, 2 => { 0 => 'idfp12', 1 =>
mm = {
0 => {
0 => 'p1',
1 => 'p2',
2 => 'p3'
},
1 => {
0 => 'idfp1',
1 => 'idfp2',
2 => 'idfp3'
},
2 => {
0 => 'idfp12',
1 => 'idfp22',
2 => 'idfp32'
}
}
我正试图用一个键为0的散列对它进行排序。在第一个散列(0)中,有k-v对数字到标识符
在每个后续散列(1和2)中,0指向第一个散列的0,1指向第一个散列的1,以此类推
在0(1和2)之后的每个散列中,都有属于p1(人员1)的id(人员1的id)
我试图通过创建一个新的散列来对其进行排序,但仅使用上面的第一个散列中的第一个散列,没有任何效果。这是我的尝试。键是正确的,但它指向的是nil
,而此时它应该指向具有每个人id的哈希
ids = {}
org = {}
mm[0].each do |id, name|
ids[id] = name
end
mm.drop(1).each do |one|
one.each do |key, id|
org[ids[key]] = id
end
end
如何在Ruby中实现这一点
编辑:
如果解释不充分,以下是预期结果:
org = {
'p1' => {
0 => 'idfp1',
1 => 'idfp12'
},
'p2' => {
0 => 'idfp2',
1 => 'idfp22'
},
'p3' => {
0 => 'idfp3',
1 => 'idfp32'
}
}
两种方式:
#1
代码
解释
#2
代码
解释
您还可以用
a.size.times.zip(a.to_h
或a.each_用索引to_h.inverse
替换Hash[[*(0…a.size)].zip(a)]
,这是更“streamy”@重写的,很好的一点,并提醒读者,数组to_h
是在Ruby 2.0中引入的。当我第一次看到这个问题时,脑海中浮现出了Hash#invert,但我并没有立即看到它可以如何使用。您对该方法的引用促使我重新思考,我添加了一种使用该方法的替代方法(“#1”),尽管不是按照您建议的方式。
mm[0].invert.each_with_object({}) { |(k,i),h|
h[k] = (1...mm.size).each_with_object ({}) { |j,g| g[j] = mm[j][i] } }
#=> {"p1"=>{1=>"idfp1", 2=>"idfp12"},
# "p2"=>{1=>"idfp2", 2=>"idfp22"},
# "p3"=>{1=>"idfp3", 2=>"idfp32"}}
a = mm[0]
#=> {0=>"p1", 1=>"p2", 2=>"p3"}
b = a.invert
#=> {"p1"=>0, "p2"=>1, "p3"=>2}
b.each_with_object({}) { |(k,i),h|
h[k] = (1...mm.size).each_with_object ({}) { |j,g| g[j] = mm[j][i] } }
#=> {"p1"=>{1=>"idfp1", 2=>"idfp12"},
# "p2"=>{1=>"idfp2", 2=>"idfp22"},
# "p3"=>{1=>"idfp3", 2=>"idfp32"}}
mm.values
.map(&:values)
.transpose
.each_with_object({}) { |a,h| h[a.shift] = Hash[[*(0...a.size)].zip(a) ] }
#=> {"p1"=>{0=>"idfp1", 1=>"idfp12"},
# "p2"=>{0=>"idfp2", 1=>"idfp22"},
# "p3"=>{0=>"idfp3", 1=>"idfp32"}}
a = mm.values
#=> [{0=>"p1", 1=>"p2", 2=>"p3" },
# {0=>"idfp1", 1=>"idfp2", 2=>"idfp3" },
# {0=>"idfp12", 1=>"idfp22", 2=>"idfp32"}]
b = a.map(&:values
#=> [[ "p1", "p2", "p3" ],
# [ "idfp1", "idfp2", "idfp3" ],
# [ "idfp12", "idfp22", "idfp32"]]
c = b.transpose
#=> [["p1", "idfp1", "idfp12"],
# ["p2", "idfp2", "idfp22"],
# ["p3", "idfp3", "idfp32"]]
c.each_with_object({}) { |a,h| h[a.shift] = Hash[[*(0...a.size)].zip(a) ] }
#=> {"p1"=>{0=>"idfp1", 1=>"idfp12"},
# "p2"=>{0=>"idfp2", 1=>"idfp22"},
# "p3"=>{0=>"idfp3", 1=>"idfp32"}}