红宝石散列组合
问题描述:
对于电子商务应用程序,我试图将选项的散列(每个选项都包含一系列选项)转换为表示这些选项组合的散列数组。例如:红宝石散列组合
# Input:
{ :color => [ "blue", "grey" ],
:size => [ "s", "m", "l" ] }
# Output:
[ { :color => "blue", :size => "s" },
{ :color => "blue", :size => "m" },
{ :color => "blue", :size => "m" },
{ :color => "grey", :size => "s" },
{ :color => "grey", :size => "m" },
{ :color => "grey", :size => "m" } ]
输入可能有它内部的附加选项与为每一个选择的人数不详,但仅会被嵌套1级深。任何
答
你可以试试:
ary = input.map {|k,v| [k].product v}
output = ary.shift.product(*ary).map {|a| Hash[a]}
结果:
[
{:color=>"blue", :size=>"s"},
{:color=>"blue", :size=>"m"},
{:color=>"blue", :size=>"l"},
{:color=>"grey", :size=>"s"},
{:color=>"grey", :size=>"m"},
{:color=>"grey", :size=>"l"}
]
答
你基本上试图在这里计算的组合,这意味着迭代的两个级别与聚合这些操作的结果的方式:
input = {:color=>["blue", "grey"], :size=>["s", "m", "l"]}
combinations = input[:color].flat_map do |color|
input[:size].collect do |size|
{ color: color, size: size }
end
end
puts combinations.inspect
# => [{:color=>"blue", :size=>"s"}, {:color=>"blue", :size=>"m"}, {:color=>"blue", :size=>"l"}, {:color=>"grey", :size=>"s"}, {:color=>"grey", :size=>"m"}, {:color=>"grey", :size=>"l"}]
这里flat_map
就派上用场了,因为它崩溃的结果的内部扩张。
答
以上的变体:
input = { color: [ "blue", "grey" ],
size: [ "s", "m", "l" ],
wt: [:light, :heavy] }
keys = input.keys
#=> [:color, :size, :wt]
values = input.values
#=> [["blue", "grey"], ["s", "m", "l"], [:light, :heavy]]
values.shift.product(*values).map { |v| Hash[keys.zip(v)] }
#=> [{:color=>"blue", :size=>"s", :wt=>:light},
# {:color=>"blue", :size=>"s", :wt=>:heavy},
# {:color=>"blue", :size=>"m", :wt=>:light},
# {:color=>"blue", :size=>"m", :wt=>:heavy},
# {:color=>"blue", :size=>"l", :wt=>:light},
# {:color=>"blue", :size=>"l", :wt=>:heavy},
# {:color=>"grey", :size=>"s", :wt=>:light},
# {:color=>"grey", :size=>"s", :wt=>:heavy},
# {:color=>"grey", :size=>"m", :wt=>:light},
# {:color=>"grey", :size=>"m", :wt=>:heavy},
# {:color=>"grey", :size=>"l", :wt=>:light},
# {:color=>"grey", :size=>"l", :wt=>:heavy}]
我认为你的意思是'shift'而不是'unshift'(如果没有给出任何参数,它不会做任何事情)。而在Ruby 2+中,FWIW可以用'map(&:to_h)',ergo:'ary.shift.product(* ary).map(&:to_h)'替换最后一个'map'。 – 2014-09-03 21:21:06
它看起来像这个解决方案与'shift'工作 – dvanderb 2014-09-03 21:23:02
@Jordan - 当然,我的意思是转变,这是晚了。 :P感谢您指出。 – BroiSatse 2014-09-03 21:23:59