数组散列的所有组合 [英] All combinations for hash of arrays

查看:60
本文介绍了数组散列的所有组合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

总结
给定一个哈希,其中一些值是数组,我如何获得所有可能组合的哈希数组?

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆