通过第一个哈希构造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"}}