将多维数组转换为ruby

时间:2017-05-25 17:33:53

标签: arrays ruby hash

我有像

这样的多维数组
arr =[['a','1','2','3'],['b','3','4','5'],['c','12','33','12'],['a','3','5','3']]

我希望这个哈希像哈希一样

hash = {
  'a'=> {
    '1'=> {'2'=> '3'},
    '3'=> {'5'=> '3'}
  },
  'b'=> {
    '3'=> {'4'=> '5'}
  },
  'c'=> {
    '12'=> {'33'=> '12'}
  } 
}

我尝试过使用合并但我不确定分配

我曾尝试使用数组中的3个元素,如

pairs = [['a','1','2'],['b','2','3']]
BLOCK_META_DATA = {}
new_hash = {}
pairs.each do |x|
  x.each_slice(3) do |a,b,c|
    new_hash[b] = c
    if BLOCK_META_DATA[a].nil?
        BLOCK_META_DATA[a] = new_hash
    else
        BLOCK_META_DATA.merge!(a => new_hash)
    end
    new_hash.clear
  end
end

但是当数组的大小增加并且普通键值出现时,它就会变得混乱

1 个答案:

答案 0 :(得分:0)

有几种方法可以做到这一点。这是一个。我使用Hash#update(又名merge!)的形式,它使用散列来确定两个哈希中合并的键的值。

arr =[%w| a 1 2 3 |, %w| b 3 4 5 |, %w| c 12 33 12 |, %w| a 3 5 3 |]
  #=> [["a", "1", "2", "3"], ["b", "3", "4", "5"],
  #    ["c", "12", "33", "12"], ["a", "3", "5", "3"]]

arr.map { |a,b,c,d| { a => { b => { c => d } } } }.
    each_with_object({}) { |g,h| h.update(g) { |_k,o,v| o.merge(v) } } 
  #=> {"a"=>{"1"=>{"2"=>"3"}, "3"=>{"5"=>"3"}},
  #    "b"=>{"3"=>{"4"=>"5"}},
  #    "c"=>{"12"=>{"33"=>"12"}}}

请参阅Hash#update的doc,了解块中三个键的描述,这三个键计算两个哈希值中合并的键的哈希值。第一个是_k,是常用密钥。我写了一个以下划线开头(你经常只看到_)来表示它没有在块计算中使用。

第一步是

arr.map { |a,b,c,d| { a => { b => { c => d } } } }
  #=> [{"a"=>{"1"=>{"2"=>"3"}}},
  #    {"b"=>{"3"=>{"4"=>"5"}}},
  #    {"c"=>{"12"=>{"33"=>"12"}}},
  #    {"a"=>{"3"=>{"5"=>"3"}}}]

然后使用h将这个包含四个哈希的数组转换为单个哈希(由块变量update表示,最初为空)。