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

如何迭代哈希数组,然后在Ruby中使用迭代的哈希值填充新的哈希键

  •  0
  • MLZ  · 技术社区  · 7 年前

    result = [
      {:label=>:road, :value=>"carl-schurz str."},
      {:label=>:house_number, :value=>"25"},
      {:label=>:postcode, :value=>"36041"},
      {:label=>:city, :value=>"fulda"},
      {:label=>:state_district, :value=>"fulda kreis"}
    ] 
    

    我想返回如下哈希值:

    output = {
      "road" => "carl-schurz str.",
      "house_number" => "25",
      "postcode" => "36041",
      "city" => "fulda",
      "state_district" => "fulda kreis"
    }
    

    因为我知道散列也可以有位置,所以我一直在尝试以下方法:

    result.each do |r|
        r.each do |key, value|
          output[value[0]] = value[1]
        end
       end 
    

    但我没有得到正确的结果。。

    5 回复  |  直到 7 年前
        1
  •  3
  •   ragurney    7 年前

    Hash[result.map { |h| [h[:label], h[:value]] }]
    

    你可以调查的另一件事是 each_with_object ,这对于构造新对象非常方便。在这种情况下,它看起来像:

    new_hash = result.each_with_object({}) do |h, r|
      r[h[:label]] = h[:value]
    end
    
        2
  •  3
  •   Cary Swoveland    7 年前
    result.map { |h| h.values_at(:label, :value) }.to_h
      #=> {:road=>"carl-schurz str.", :house_number=>"25", :postcode=>"36041", 
      #    :city=>"fulda", :state_district=>"fulda kreis"}
    
        3
  •  3
  •   maerics    7 年前

    你可以很容易地用“地图”。。。

    result.map { |h| [h[:label], h[:value]] }.to_h
    Hash[result.map { |h| [h[:label], h[:value]] }]
    

    result.reduce(Hash.new) { |h,o| h[o[:label]] = o[:value]; h }
    

    这个简单的基准表明,“reduce”形式比其他形式稍微快一些:

    require 'benchmark'
    
    result = [
      {:label=>:road, :value=>"carl-schurz str."},
      {:label=>:house_number, :value=>"25"},
      {:label=>:postcode, :value=>"36041"},
      {:label=>:city, :value=>"fulda"},
      {:label=>:state_district, :value=>"fulda kreis"}
    ] 
    
    n = 1_000_000
    
    Benchmark.bmbm do |x|
      x.report('Hash[]    ') { n.times { Hash[result.map { |h| [h[:label], h[:value]] }] } }
      x.report('map...to_h') { n.times { result.map { |h| [h[:label], h[:value]] }.to_h } }
      x.report('reduce    ') { n.times { result.reduce(Hash.new) { |h,o| h[o[:label]] = o[:value]; h } } }
    end
    
    #                  user     system      total        real
    # Hash[]       1.830000   0.040000   1.870000 (  1.882664)
    # map...to_h   1.760000   0.040000   1.800000 (  1.810998)
    # reduce       1.590000   0.030000   1.620000 (  1.633808) *
    
        4
  •  2
  •   iGian    7 年前

    还有一种方法:

    result.map.with_object({}) { |h, new_h| new_h[h[:label]] = h[:value] }
    
        5
  •  0
  •   MLZ    7 年前

    我可以使用以下方法获得所需的结果:

    result.each do |r|
      output[r.values[0]] = values[1]
    end
    

    知道如何使用hash\u object.values是关键。

    推荐文章