【问题标题】:Build one hash from an array of many hashes using Ruby使用 Ruby 从包含许多哈希的数组中构建一个哈希
【发布时间】:2014-05-03 19:31:43
【问题描述】:

我有一个哈希数组:

[{:key=>"RepositoryKey", :value=>"6958127"}, 
{:key=>"Guid", :value=>"006444a2-3ea1-4b64-81b8-51ce4756d337"}, 
{:key=>"Association_Guid", :value=>"05500000-93ba-4898-8308-444a25df7eb6"},
{:key=>"Association_Type", :value=>"Association"},
{:key=>"Association_Name", :value=>"Hancock Wellness Center"}, 
{:key=>"Image_Guid", :value=>nil}, 
{:key=>"Image_Type", :value=>"StoredFile"}]

这来自外部来源,我需要将某些值组合成一个哈希值。例如,我想要上面数组中的RepositoryKeyGuidAssociation_Type。最后我想要这样的东西:

hash = {"RepositoryKey" => "6958127", 
        "Guid" => "006444a2-3ea1-4b64-81b8-51ce4756d337", 
        "Association_Type" => "Association"}

使用 Ruby 2.0.0 对我来说最好的方法是什么?

【问题讨论】:

    标签: ruby arrays hash


    【解决方案1】:

    如果你想要数组中的一些特定项目,那么如下:

    array_of_hash = [
             {:key=>"RepositoryKey", :value=>"6958127"}, 
             {:key=>"Guid", :value=>"006444a2-3ea1-4b64-81b8-51ce4756d337"}, 
             {:key=>"Association_Guid", :value=>"05500000-93ba-4898-8308-444a25df7eb6"},
             {:key=>"Association_Type", :value=>"Association"},
             {:key=>"Association_Name", :value=>"Hancock Wellness Center"}, 
             {:key=>"Image_Guid", :value=>nil}, 
             {:key=>"Image_Type", :value=>"StoredFile"}
           ]
    
    array = ["RepositoryKey", "Guid", "Association_Type"]
    
    Hash[array_of_hash.select { |h| array.include?(h[:key]) }.map(&:values)]
    # => {"RepositoryKey"=>"6958127",
    #     "Guid"=>"006444a2-3ea1-4b64-81b8-51ce4756d337",
    #     "Association_Type"=>"Association"}
    

    如果你想要完整的哈希

    Hash[array_of_hash.map(&:values)]
    # => {"RepositoryKey"=>"6958127",
    #     "Guid"=>"006444a2-3ea1-4b64-81b8-51ce4756d337",
    #     "Association_Guid"=>"05500000-93ba-4898-8308-444a25df7eb6",
    #     "Association_Type"=>"Association",
    #     "Association_Name"=>"Hancock Wellness Center",
    #     "Image_Guid"=>nil,
    #     "Image_Type"=>"StoredFile"}
    

    如果您使用的是 Ruby 2.1 版本

    array_of_hash.map(&:values).to_h
    

    奖金:

    如果每个inner hash的key比例子多,你想得到:key:value的值,那么写如下:

    array_of_hash.map { |h| h.values_at(:key, :value) }.to_h
    

    【讨论】:

    • 是的,这很好。不好的是有一个名为hash 的变量定义了一个数组^_^(开玩笑)。无论如何,他可能想在一开始就创建大哈希并使用它,特别是如果他需要多次提取值。 +1
    • @DaniëlKnippers 感谢您教导何时给变量,给变量取什么名字.. :-)
    • 不要使用带有条件的map,而是使用compact,使用selectreject来查找您想要的元素,然后map他们。事后使用compact 是代码异味。
    • @theTinMan 这很好。我也想过,但没有写,因为我创建了很多中间数组。但是你的想法是 100% 好的并且可以接受的。
    【解决方案2】:

    试试这个

    array = [{:key=>"RepositoryKey", :value=>"6958127"}, 
             {:key=>"Guid", :value=>"006444a2-3ea1-4b64-81b8-51ce4756d337"}, 
             {:key=>"Association_Guid", :value=>"05500000-93ba-4898-8308-444a25df7eb6"},
             {:key=>"Association_Type", :value=>"Association"},
             {:key=>"Association_Name", :value=>"Hancock Wellness Center"}, 
             {:key=>"Image_Guid", :value=>nil}, 
             {:key=>"Image_Type", :value=>"StoredFile"}]
    hash = Hash[array.map{|h| [h[:key],h[:value]]}]
    #=> {"RepositoryKey"=>"6958127", "Guid"=>"006444a2-3ea1-4b64-81b8-51ce4756d337", "Association_Guid"=>"05500000-93ba-4898-8308-444a25df7eb6", "Association_Type"=>"Association", "Association_Name"=>"Hancock Wellness Center", "Image_Guid"=>nil, "Image_Type"=>"StoredFile"}
    

    两全其美的完整哈希,您可以拒绝以后不想要的值

    wanted_values = ["RepositoryKey", "Guid", "Association_Type"]
    hash.reject{|k,v| !wanted_values.include?(k)}
    #=>{"RepositoryKey"=>"6958127", "Guid"=>"006444a2-3ea1-4b64-81b8-51ce4756d337","Association_Type"=>"Association"}
    hash
    #=>=> {"RepositoryKey"=>"6958127", "Guid"=>"006444a2-3ea1-4b64-81b8-51ce4756d337", "Association_Guid"=>"05500000-93ba-4898-8308-444a25df7eb6", "Association_Type"=>"Association", "Association_Name"=>"Hancock Wellness Center", "Image_Guid"=>nil, "Image_Type"=>"StoredFile"}
    

    【讨论】:

    • 这还没有被问到.. 他想要一些我认为的项目 - 假设我想要上述数组中的 RepositoryKey、Guid 和 Association_Type。..
    • I want something like this in the end: 我认为它有我认为他可能只是为了简洁起见。另外,当他可以访问所有需要的属性以及必要时更多的属性时,为什么还要处理数据销毁
    • @engineersmnky 有效点。我原本打算只选择特定的值,但保留它们以备不时之需。
    【解决方案3】:
    array_of_hash = [
             {:key=>"RepositoryKey", :value=>"6958127"}, 
             {:key=>"Guid", :value=>"006444a2-3ea1-4b64-81b8-51ce4756d337"}, 
             {:key=>"Association_Guid", :value=>"05500000-93ba-4898-8308-444a25df7eb6"},
             {:key=>"Association_Type", :value=>"Association"},
             {:key=>"Association_Name", :value=>"Hancock Wellness Center"}, 
             {:key=>"Image_Guid", :value=>nil}, 
             {:key=>"Image_Type", :value=>"StoredFile"}
           ]
    
    array = ["RepositoryKey", "Guid", "Association_Type"]
    
    array_of_hash.select{|h| array.include? h[:key]}.map{|h| 
                         Hash[*h.values]}.reduce Hash.new, :merge
    #=> {"RepositoryKey"=>"6958127", "Guid"=>"006444a2-3ea1-4b64-81b8-51ce4756d337", "As#ociation_Type"=>"Association"}
    

    【讨论】:

      【解决方案4】:

      早期答案的变体:

      代码

      arr.each_with_object({}) { |h,g| g[h.values.first] = h.values.last }
         .select { |k,_| target.include?(k) }
      

      演示

      arr = [
               {:key=>"RepositoryKey", :value=>"6958127"}, 
               {:key=>"Guid", :value=>"006444a2-3ea1-4b64-81b8-51ce4756d337"}, 
               {:key=>"Association_Guid", :value=>"05500000-93ba-4898-8308-444a25df7eb6"},
               {:key=>"Association_Type", :value=>"Association"},
               {:key=>"Association_Name", :value=>"Hancock Wellness Center"}, 
               {:key=>"Image_Guid", :value=>nil}, 
               {:key=>"Image_Type", :value=>"StoredFile"}
             ]
      
      target = ["RepositoryKey", "Guid", "Association_Type"]
      
      arr.each_with_object({}) { |h,g| g[h.values.first] = h.values.last }
         .select { |k,_| target.include?(k) }
        #=> {"RepositoryKey"=>"6958127",
        #    "Guid"=>"006444a2-3ea1-4b64-81b8-51ce4756d337",
        #    "Association_Type"=>"Association"} 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-19
        • 1970-01-01
        • 2015-01-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多