数组散列的所有组合 [英] All combinations for hash of arrays
问题描述
总结
给定一个哈希,其中一些值是数组,我如何获得所有可能组合的哈希数组?
Summary
Given a Hash where some of the values are arrays, how can I get an array of hashes for all possible combinations?
测试用例
options = { a:[1,2], b:[3,4], c:5 }
p options.self_product
#=> [{:a=>1, :b=>3, :c=>5},
#=> {:a=>1, :b=>4, :c=>5},
#=> {:a=>2, :b=>3, :c=>5},
#=> {:a=>2, :b=>4, :c=>5}]
当特定键的值不是数组时,它应该简单地按原样包含在每个结果散列中,就像它被包装在一个数组中一样.
动机
我需要根据不同选项的各种值生成测试数据.虽然我可以使用 [1,2].product([3,4],[5])
来获取所有可能值的笛卡尔积,我宁愿使用哈希来标记我的输入和输出,以便代码比仅使用数组索引更容易解释.
Motivation
I need to generate test data given a variety of values for different options. While I can use [1,2].product([3,4],[5])
to get the Cartesian Product of all possible values, I'd rather use hashes to be able to label both my input and output so that the code is more self-explanatory than just using array indices.
推荐答案
我建议进行一些预处理以保持结果一般:
I suggest a little pre-processing to keep the result general:
options = { a:[1,2], b:[3,4], c:5 }
options.each_key {|k| options[k] = [options[k]] unless options[k].is_a? Array}
=> {:a=>[1, 2], :b=>[3, 4], :c=>[5]}
我进行了一些改进,主要是使用了inject({})
:
I edited to make a few refinements, principally the use of inject({})
:
class Hash
def self_product
f, *r = map {|k,v| [k].product(v).map {|e| Hash[*e]}}
f.product(*r).map {|a| a.inject({}) {|h,e| e.each {|k,v| h[k]=v}; h}}
end
end
...虽然我更喜欢@Phrogz 的第二次尝试",经过预处理 5=>[5]
,将是:
...though I prefer @Phrogz's '2nd attempt', which, with pre-processing 5=>[5]
, would be:
class Hash
def self_product
f, *r = map {|k,v| [k].product(v)}
f.product(*r).map {|a| Hash[*a.flatten]}
end
end
这篇关于数组散列的所有组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!