如何在条件下合并哈希数组的哈希数组?

时间:2015-12-24 12:18:02

标签: arrays ruby hash merge

目标是合并数组,如果它具有相同的值,但会继承其中的现有哈希数组。

到目前为止

代码:

aff_packages = [{:platform=>"platform 5", :pkg=>"package1", :state=>"somestate"},
                {:platform=>"platform 7", :pkg=>"package2", :state=>"somestate"},
                {:platform=>"platform 5", :pkg=>"package3", :state=>"somestate"},
                {:platform=>"platform 5", :pkg=>"package4", :state=>"somestate"},
                {:platform=>"platform 7", :pkg=>"package5", :state=>"somestate"},
                {:platform=>"platform 6", :pkg=>"package6", :state=>"somestate"
                }]

  aff_packages.each do |package|

    small_array = []
    print_me = big_array = []
    hash = Hash.new
    print_me << hash

    small_array << {
        package: package[:pkg],
        state:  package[:state]
    }

    (hash[package[:platform]] ||= small_array)

    end

产生:

[{"platform 5"=>[{:package=>"package1", :state=>"somestate"}]}]
[{"platform 7"=>[{:package=>"package2", :state=>"somestate"}]}]
[{"platform 5"=>[{:package=>"package3", :state=>"somestate"}]}]
[{"platform 5"=>[{:package=>"package4", :state=>"somestate"}]}]
[{"platform 7"=>[{:package=>"package5", :state=>"somestate"}]}]
[{"platform 6"=>[{:package=>"package6", :state=>"somestate"}]}]

如何将相同的平台合并在一起,但是继承了哈希数组并将其附加如下:

[{"platform 5"=>[{:package=>"package1", :state=>"somestate"}], [{:package=>"package3", :state=>"somestate"}], [{:package=>"package4", :state=>"somestate"}]}]
[{"platform 7"=>[{:package=>"package2", :state=>"somestate"}], [{:package=>"package5", :state=>"somestate"}]}]
[{"platform 6"=>[{:package=>"package6", :state=>"somestate"}]}]

2 个答案:

答案 0 :(得分:2)

这是一种可能的解决方案。

输入代码:

var myObservableArray = ko.observableArray([
    { name: "Bungle", type: "Unknown" },
    { name: "George", type: "Unknown" },
    { name: "Zippy", type: "Unknown" }
]); 

第1步:使用平台作为键创建哈希,其余属性作为值哈希

aff_packages = [{:platform=>"platform 5", :pkg=>"package1", :state=>"somestate"},
                {:platform=>"platform 7", :pkg=>"package2", :state=>"somestate"},
                {:platform=>"platform 5", :pkg=>"package3", :state=>"somestate"},
                {:platform=>"platform 5", :pkg=>"package4", :state=>"somestate"},
                {:platform=>"platform 7", :pkg=>"package5", :state=>"somestate"},
                {:platform=>"platform 6", :pkg=>"package6", :state=>"somestate"
                }]

此时,ary = aff_packages.map do |package| # Let's create a copy as we don't want to modify aff_packages pkg = package.dup # Remove :platform's value from pkg hash platform = pkg.delete(:platform) # Return platform name and rest of hash as key-value { platform => pkg } end 是一个散列数组,如下所示:

ary

第2步:我们现在有哈希数组,让我们合并哈希值,这样对于给定的键,值会被收集为数组。

[{"platform 5"=>{:pkg=>"package1", :state=>"somestate"}}, 
 {"platform 7"=>{:pkg=>"package2", :state=>"somestate"}}, 
 {"platform 5"=>{:pkg=>"package3", :state=>"somestate"}}, 
 {"platform 5"=>{:pkg=>"package4", :state=>"somestate"}}, 
 {"platform 7"=>{:pkg=>"package5", :state=>"somestate"}}, 
 {"platform 6"=>{:pkg=>"package6", :state=>"somestate"}}]

请注意,我们正在使用Enumerable#reduce来收集新h = ary.reduce(Hash.new{|hash, k| hash[k] = []}) do |memo, i| memo[i.keys.first] << i.values.first; memo end 中的值。另外,请注意Hash#new的块语法的使用,它允许每个键的默认值为空数组。

此时,我们有哈希Hash,其值如下所示。

h

通常,这是期望的输出。

第3步:您似乎需要输出,其中表示平台的每个键值对都位于其自己的数组中。我们需要此步骤将步骤2中的哈希转换为所需的输出。

{"platform 5"=>
  [{:pkg=>"package1", :state=>"somestate"},
   {:pkg=>"package3", :state=>"somestate"},
   {:pkg=>"package4", :state=>"somestate"}],
 "platform 7"=>
  [{:pkg=>"package2", :state=>"somestate"},
   {:pkg=>"package5", :state=>"somestate"}],
 "platform 6"=>[{:pkg=>"package6", :state=>"somestate"}]}

此时,output = h.map {|k,v| [{k => v}]} 值如下所示:

output

附注

要漂亮地打印哈希和数组,你可以使用Ruby的PP class。例如,

[[{"platform 5"=>
    [{:pkg=>"package1", :state=>"somestate"},
     {:pkg=>"package3", :state=>"somestate"},
     {:pkg=>"package4", :state=>"somestate"}]}],
 [{"platform 7"=>
    [{:pkg=>"package2", :state=>"somestate"},
     {:pkg=>"package5", :state=>"somestate"}]}],
 [{"platform 6"=>[{:pkg=>"package6", :state=>"somestate"}]}]]

答案 1 :(得分:0)

您可以使用group_by。这里:

aff_packages.group_by { |a| a[:platform] }
# => {"platform 5"=>[{:platform=>"platform 5", :pkg=>"package1", :state=>"somestate"}, {:platform=>"platform 5", :pkg=>"package3", :state=>"somestate"}, {:platform=>"platform 5", :pkg=>"package4", :state=>"somestate"}],
# "platform 7"=>[{:platform=>"platform 7", :pkg=>"package2", :state=>"somestate"}, {:platform=>"platform 7", :pkg=>"package5", :state=>"somestate"}],
# "platform 6"=>[{:platform=>"platform 6", :pkg=>"package6", :state=>"somestate"}]}