# Input: # choices = { # 'color' => %w(blue red green), # 'sizes' => %w(small medium large extra-large), # 'style' => %w(tshirt longsleeve) # } # # Output: # [{"sizes"=>"small", "color"=>"blue", "style"=>"tshirt"}, # {"sizes"=>"small", "color"=>"blue", "style"=>"longsleeve"}, # {"sizes"=>"medium", "color"=>"blue", "style"=>"tshirt"}, # {"sizes"=>"medium", "color"=>"blue", "style"=>"longsleeve"}, # {"sizes"=>"large", "color"=>"blue", "style"=>"tshirt"}, # {"sizes"=>"large", "color"=>"blue", "style"=>"longsleeve"}, # {"sizes"=>"extra-large", "color"=>"blue", "style"=>"tshirt"}, # {"sizes"=>"extra-large", "color"=>"blue", "style"=>"longsleeve"}, # {"sizes"=>"small", "color"=>"red", "style"=>"tshirt"}, # {"sizes"=>"small", "color"=>"red", "style"=>"longsleeve"}, # {"sizes"=>"medium", "color"=>"red", "style"=>"tshirt"}, # {"sizes"=>"medium", "color"=>"red", "style"=>"longsleeve"}, # {"sizes"=>"large", "color"=>"red", "style"=>"tshirt"}, # {"sizes"=>"large", "color"=>"red", "style"=>"longsleeve"}, # {"sizes"=>"extra-large", "color"=>"red", "style"=>"tshirt"}, # {"sizes"=>"extra-large", "color"=>"red", "style"=>"longsleeve"}, # {"sizes"=>"small", "color"=>"green", "style"=>"tshirt"}, # {"sizes"=>"small", "color"=>"green", "style"=>"longsleeve"}, # {"sizes"=>"medium", "color"=>"green", "style"=>"tshirt"}, # {"sizes"=>"medium", "color"=>"green", "style"=>"longsleeve"}, # {"sizes"=>"large", "color"=>"green", "style"=>"tshirt"}, # {"sizes"=>"large", "color"=>"green", "style"=>"longsleeve"}, # {"sizes"=>"extra-large", "color"=>"green", "style"=>"tshirt"}, # {"sizes"=>"extra-large", "color"=>"green", "style"=>"longsleeve"}] class Hash def permutations_of_arrays permute(map {|key, vals| vals.map {|val| [key, val]} }).map {|pairs| Hash[pairs]} end private def permute(arrs) fst, rst = arrs[0], arrs[1..-1] init = fst.map {|x| [x]} rst.inject(init) {|acc, opts| permute_merge(acc, opts)} end def permute_merge(acc, to_merge) acc.map {|acc_arr| to_merge.map do |to_merge_el| acc_arr + [to_merge_el] end }.flatten(1) end end