Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save MichaelXavier/1214355 to your computer and use it in GitHub Desktop.
Save MichaelXavier/1214355 to your computer and use it in GitHub Desktop.
Permutations of a hash of arrays
# 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment