Ruby中数组散列的所有可能组合 [英] All possible combinations from a hash of arrays in Ruby

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

问题描述

我有什么:



假设我有这样的散列,各种值都属于一个参数。

  a = {} 
a [:bitrate] = [100,500,1000]
a [:fps] = [ 15,30]
a [:qp] = [20,30]






我需要:



我需要一些方法来迭代获取所有这些值的可能组合,所以,所有的参数/值对:


  • bitrate = 100 fps = 15 qp = 20

  • bitrate = 500 fps = 15 qp = 30

  • ...



参数的数量(即键)和值的数量(即值数组的长度)事先不知道。理想情况下,我会这样做:

  a.foo do | ret | 
puts ret.keys#=> [bitrate,fps,qp]
puts ret.values#=> [100,15,20]
结束

...其中块被称为每个可能的组合。我如何定义 foo






不需要:

现在,我知道这一点:组合数组数组进入所有可能的组合,仅在Ruby中转发,提示如下:

  a.first.product(* a [1 ..- 1])。map(&:join)

值和数组只在数组中,并且我需要对参数名称的原始引用。

解决方案

  a = {} 
a [:bitrate] = [100,500,1000]
a [:fps] = [15,30]
a [:qp] = [20,30]

def product_hash(hsh)
attrs = hsh.values
keys = hsh.keys
product = attrs [0] .product(* attrs [1 ..- 1])$ ​​b $ b product.map {| p | Hash [keys.zip p]}
结束

product_hash(a)

你会得到

  [{:bitrate =>100,:fps =>15 ,:qp =>20},
{:bitrate =>100,:fps =>15,:qp =>30 :比特率=>100,::fps =>30,::qp =>20},
{:比特率=>100 ::qp =>30},
{:bitrate =>500,:fps =>15,:qp =>20 bitrate =>500,:fps =>15,::qp =>30},
{:bitrate =>500,:fps =>30 :qp =>20},
{:比特率=>500,:fps =>30,::qp =>30},
{ =1000,:fps =>15,::qp =>20},
{:bitrate =>1000,:fps =>15 qp => 30},
{:比特率=>1000,:fps =>30,::qp =>20},
{:bitrate = >1000,:fps =>30,::qp =>30}]

您还可以将新密钥添加到散列中。

  a = {} 
a [:bitrate] = [100,500,1000]
a [:fps] = [15,30]
a [:qp] = [20,30]
a [:bw] = [true,false]

product_hash(a)

#=>
[{:bitrate =>100,:fps =>15,:qp =>20,:bw => true},
{:bitrate => ;100,::fps =>15,::qp =>20,:bw => false},
{:bitrate =>100,:fps => 15:qp =30,:bw => true},
{:bitrate =>100,:fps =>15,:qp => 30,bw => false},
{:bitrate =>100,:fps =>30,:qp =>20,:bw => true} ,
{:bitrate =>100,:fps =>30,:qp =>20,:bw => false},
{:bitrate => ;100,::fps =>30,:qp =>30,:bw => true},
{:bitrate =>100,:fps => 30,:qp =>30,:bw => false},
{:bitrate =>500,:fps =>15,:qp => 20,:bw => true},
{:bitrate =>500,:fps =>15,:qp =>20,:bw => false} ,
{:bitrate =>500,:fps =>15,:qp =>30,:bw => true},
{:bitrate => ;500,:fps =>15,::qp =>30,:bw => false},
{:bitrate =>500,:fps => 30,::qp =>20,:bw => true},
{:bitrate =>500,:fps =>30,:qp => 20,:bw => false},
{:bitrate =>500,:fps =>30,:qp =>30,:bw => true},
{:bitrate => 500,:fps =>30,:qp =>30,:bw => false},
{:bitrate =>1000,:fps => 15,::qp =>20,::bw => true},
{:bitrate =>1000,:fps =>15,:qp =>20 :bw => false},
{:bitrate =>1000,:fps =>15,::qp =>30,:bw => true},
{:bitrate =>1000,:fps =>15,:qp =>30,:bw => false},
{:bitrate => 1000,:fps =>30,::qp =>20,:bw => true},
{:bitrate =>1000,:fps => 30::qp =>20,:bw => false},
{:bitrate =>1000,:fps =>30,:qp =>30 :bw => true},
{:bitrate =>1000,:fps =>30,::qp =>30,:bw => false}]


What I have:

Let's say I have a hash like this, with various values belonging to one parameter.

a = {}
a[:bitrate] = ["100", "500", "1000"]
a[:fps] = ["15", "30"]
a[:qp] = ["20", "30"]


What I need:

I need some way to iteratively get all the possible combinations of these values, so, with all the parameter/value pairs:

  • bitrate = 100, fps = 15, qp = 20
  • bitrate = 500, fps = 15, qp = 30
  • ...

The number of parameters (i.e. the keys) and the number of values (i.e. the length of the value arrays) are not known beforehand. Ideally, I'd do something like:

a.foo do |ret|
  puts ret.keys   # => ["bitrate", "fps", "qp"]
  puts ret.values # => ["100", "15", "20"]
end

… where the block is called for each possible combination. How can I define foo?


What I (probably) don't need:

Now, I know this: Combine array of array into all possible combinations, forward only, in Ruby, suggesting something like:

a.first.product(*a[1..-1]).map(&:join)

But this operates on values and arrays in arrays only, and I need the original reference to the parameter's name.

解决方案

a = {}
a[:bitrate] = ["100", "500", "1000"]
a[:fps] = ["15", "30"]
a[:qp] = ["20", "30"]

def product_hash(hsh)
  attrs   = hsh.values
  keys    = hsh.keys
  product = attrs[0].product(*attrs[1..-1])
  product.map{ |p| Hash[keys.zip p] }
end

product_hash(a)

you'll get

[{:bitrate=>"100", :fps=>"15", :qp=>"20"},
 {:bitrate=>"100", :fps=>"15", :qp=>"30"},
 {:bitrate=>"100", :fps=>"30", :qp=>"20"},
 {:bitrate=>"100", :fps=>"30", :qp=>"30"},
 {:bitrate=>"500", :fps=>"15", :qp=>"20"},
 {:bitrate=>"500", :fps=>"15", :qp=>"30"},
 {:bitrate=>"500", :fps=>"30", :qp=>"20"},
 {:bitrate=>"500", :fps=>"30", :qp=>"30"},
 {:bitrate=>"1000", :fps=>"15", :qp=>"20"},
 {:bitrate=>"1000", :fps=>"15", :qp=>"30"},
 {:bitrate=>"1000", :fps=>"30", :qp=>"20"},
 {:bitrate=>"1000", :fps=>"30", :qp=>"30"}]

You can also add new key to your hash.

a = {}
a[:bitrate] = ["100", "500", "1000"]
a[:fps] = ["15", "30"]
a[:qp] = ["20", "30"]
a[:bw] = [true, false]

product_hash(a)

#=>
[{:bitrate=>"100", :fps=>"15", :qp=>"20", :bw=>true},
 {:bitrate=>"100", :fps=>"15", :qp=>"20", :bw=>false},
 {:bitrate=>"100", :fps=>"15", :qp=>"30", :bw=>true},
 {:bitrate=>"100", :fps=>"15", :qp=>"30", :bw=>false},
 {:bitrate=>"100", :fps=>"30", :qp=>"20", :bw=>true},
 {:bitrate=>"100", :fps=>"30", :qp=>"20", :bw=>false},
 {:bitrate=>"100", :fps=>"30", :qp=>"30", :bw=>true},
 {:bitrate=>"100", :fps=>"30", :qp=>"30", :bw=>false},
 {:bitrate=>"500", :fps=>"15", :qp=>"20", :bw=>true},
 {:bitrate=>"500", :fps=>"15", :qp=>"20", :bw=>false},
 {:bitrate=>"500", :fps=>"15", :qp=>"30", :bw=>true},
 {:bitrate=>"500", :fps=>"15", :qp=>"30", :bw=>false},
 {:bitrate=>"500", :fps=>"30", :qp=>"20", :bw=>true},
 {:bitrate=>"500", :fps=>"30", :qp=>"20", :bw=>false},
 {:bitrate=>"500", :fps=>"30", :qp=>"30", :bw=>true},
 {:bitrate=>"500", :fps=>"30", :qp=>"30", :bw=>false},
 {:bitrate=>"1000", :fps=>"15", :qp=>"20", :bw=>true},
 {:bitrate=>"1000", :fps=>"15", :qp=>"20", :bw=>false},
 {:bitrate=>"1000", :fps=>"15", :qp=>"30", :bw=>true},
 {:bitrate=>"1000", :fps=>"15", :qp=>"30", :bw=>false},
 {:bitrate=>"1000", :fps=>"30", :qp=>"20", :bw=>true},
 {:bitrate=>"1000", :fps=>"30", :qp=>"20", :bw=>false},
 {:bitrate=>"1000", :fps=>"30", :qp=>"30", :bw=>true},
 {:bitrate=>"1000", :fps=>"30", :qp=>"30", :bw=>false}]

这篇关于Ruby中数组散列的所有可能组合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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