代码之家  ›  专栏  ›  技术社区  ›  mechnicov

将哈希转换为哈希数组

  •  2
  • mechnicov  · 技术社区  · 7 年前

    我有散列,它的所有值都是数组,如下所示:

    list = { letter:  ['a', 'b', 'c'],
             number:  ['one', 'two', 'three'],
             fruit:   ['apple', 'pear', 'kiwi'],
             car:     ['vw', 'mb', 'bmw'],
             state:   ['la', 'ny', 'fl'],
             color:   ['red', 'white', 'black'],
             tree:    ['oak', 'pine', 'maple'],
             animal:  ['cat', 'dog', 'rat'],
             clothes: ['tie', 'sock', 'glove'] }
    

    事实上,这个散列可以有更多的键,值也可以更大,但每个值的大小总是相同的(在本例中为-3)。

    我想把这个散列转换成散列数组。

    每个散列将具有所有源散列键和各自的值。

    最后,我想:

    list = [
      { letter: 'a', number: 'one', fruit: 'apple', car: 'vw', state: 'la',
        color: 'red', tree: 'oak', animal: 'cat', clothes: 'tie' },
    
      { letter: 'b', number: 'two', fruit: 'pear', car: 'mb', state: 'ny',
        color: 'white', tree: 'pine', animal: 'dog', clothes: 'sock' },
    
      { letter: 'c', number: 'three', fruit: 'kiwi', car: 'bmw', state: 'fl',
        color: 'black', tree: 'elm', animal: 'rat', clothes: 'glove' }
    ]
    

    5 回复  |  直到 7 年前
        1
  •  8
  •   Cary Swoveland    7 年前
    [list.keys].product(list.values.transpose).map { |a| a.transpose.to_h }
       #=> [{:letter=>"a", :number=>"one", :fruit=>"apple", :car=>"vw", 
       #     :state=>"la", :color=>"red", :tree=>"oak", :animal=>"cat",
       #     :clothes=>"tie"},
       #    {:letter=>"b", :number=>"two", :fruit=>"pear", :car=>"mb",
       #     :state=>"ny", :color=>"white", :tree=>"pine", :animal=>"dog",
       #     :clothes=>"sock"},
       #    {:letter=>"c", :number=>"three", :fruit=>"kiwi", :car=>"bmw",
       #     :state=>"fl", :color=>"black", :tree=>"maple", :animal=>"rat", 
       #     :clothes=>"glove"}]
    

    list 定义如下。

    list = {
      letter:  ['a',     'b'   ],
      number:  ['one',   'two' ],
      fruit:   ['apple', 'pear'],
      car:     ['vw',    'mb'  ]
    }
    

    b = [list.keys]
      #=> [[:letter, :number, :fruit, :car]]
    c = list.values
      #=> [["a", "b"], ["one", "two"], ["apple", "pear"], ["vw", "mb"]]
    d = c.transpose
      #=> [["a", "one", "apple", "vw"],
      #    ["b", "two", "pear",  "mb"]]
    e = b.product(d)
      #=> [[[:letter, :number, :fruit, :car], ["a", "one", "apple", "vw"]],
      #    [[:letter, :number, :fruit, :car], ["b", "two", "pear",  "mb"]]]
    e.map { |a| a.transpose.to_h }
      #=> [{:letter=>"a", :number=>"one", :fruit=>"apple", :car=>"vw"},
      #    {:letter=>"b", :number=>"two", :fruit=>"pear",  :car=>"mb"}]
    

    让我们更仔细地看最后一步。 map e 添加到块并设置块变量 a 对于其价值:

    a = e.first
      #=> [[:letter, :number,  :fruit,  :car],
      #    ["a",     "one",    "apple", "vw"]]
    

    区块计算如下所示。

    f = a.transpose
      #=> [[:letter, "a"], [:number, "one"], [:fruit, "apple"], [:car,   "vw"]]
    f.to_h
      #=> {:letter=>"a", :number=>"one", :fruit=>"apple", :car=>"vw"}
    

    剩余的计算 e.map { |a| a.transpose.to_h }

        2
  •  4
  •   Marcin Kołodziej    7 年前

    Array#transpose Array#to_h

    keys = list.keys
    list.values.transpose.map { |v| keys.zip(v).to_h }
    
        3
  •  3
  •   Tyl    7 年前

    一应俱全:

    list.map{|k,v| [k].product(v)}.transpose.map(&:to_h)
    

    to_h .

        4
  •  2
  •   ray    7 年前

    试试下面的代码,

    arr = []
    3.times { |x| arr[x] = {}; list.each { |k,v| arr[x][k] = v[x] } }
    arr.inspect
    

    => [{:letter=>"a", :number=>"one", :fruit=>"apple", :car=>"vw", :state=>"la", :color=>"red", :tree=>"oak", :animal=>"cat", :clothes=>"tie"}, {:letter=>"b", :number=>"two", :fruit=>"pear", :car=>"mb", :state=>"ny", :color=>"white", :tree=>"pine", :animal=>"dog", :clothes=>"sock"}, {:letter=>"c", :number=>"three", :fruit=>"kiwi", :car=>"bmw", :state=>"fl", :color=>"black", :tree=>"maple", :animal=>"rat", :clothes=>"glove"}]
    
        5
  •  0
  •   iGian    7 年前

    只是玩玩 Enumerable#each_with_object :

    list.values.transpose.each_with_object([]) { |v, a| a << v.each_with_index.with_object({}) { |(vv, i), h| h[list.keys[i]] = vv } }