Ruby on rails Ruby哈希组合
对于一个电子商务应用程序,我试图将选项的散列(每个选项都有一个选项数组)转换为表示这些选项组合的散列数组。例如:Ruby on rails Ruby哈希组合,ruby-on-rails,ruby,arrays,hash,combinations,Ruby On Rails,Ruby,Arrays,Hash,Combinations,对于一个电子商务应用程序,我试图将选项的散列(每个选项都有一个选项数组)转换为表示这些选项组合的散列数组。例如: # Input: { :color => [ "blue", "grey" ], :size => [ "s", "m", "l" ] } # Output: [ { :color => "blue", :size => "s" }, { :color => "blue", :size => "m" }, { :color =>
# 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" } ]
输入中可能有额外的选项,每个选项的选择数量不确定,但它只能嵌套一层。任何您基本上是在这里尝试计算组合,这意味着两个层次的迭代,以一种聚合这些操作结果的方式:
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\u map
很方便,因为它可以折叠内部扩展的结果。您可以尝试:
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" ],
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}]
请尝试选项组合生成器
需要“ocg”
发电机=OCG.new(
:color=>%w[蓝灰色],
:大小=>%w[s m l]
)
将generator.next置于generator.finished之前?
Generator包含更多功能,可帮助您处理其他选项。谢谢。我试图找到一种更通用的方法来实现这一点,它不依赖于输入哈希的键,因为这些键将是用户的inputs@mu-太短了,你说得对。同时,我认为当我说“输入可能有额外的选项,每个选项的数量不确定”时,这是暗示。我认为这个解决方案不能很好地处理这种情况。我认为您的意思是
shift
,而不是unshift
(如果没有给出任何参数,它不会起任何作用)。在Ruby 2+中,你可以用map(&:to_h)
替换上一个map(&:to_h)
,因此:ari.shift.product(*ari).map(&:to_h)
@Jordan-当然我是说shift,已经晚了P谢谢你指出它。@BroiSatse这是一个很好的解决方案,尽管对初学者来说可能有点不透明。就我个人而言,我认为分解赋值比移位要好一些:首先,*rest=input.map{k,v}[k].product v};输出=first.product(*rest).map(&:to_h)
。但那只是我