ruby - 用每个可能的值填充散列中的通配符值

标签 ruby cartesian-product

给定一组可能值和任意数量值的散列,我如何用可能值的所有可能组合替换每个 nil 值?

例如:

values = %w[a b c]
hash   = { x:1, y:2, z:nil }
fill_wildcards( hash, values )
#=> [{ x:1, y:2, z:'a' },
#=>  { x:1, y:2, z:'b' },
#=>  { x:1, y:2, z:'c' }]

hash   = { x:1, y:nil, z:nil }
fill_wildcards( hash, values )
#=> [{ x:1, y:'a', z:'a' },
#=>  { x:1, y:'a', z:'b' },
#=>  { x:1, y:'a', z:'c' },
#=>  { x:1, y:'b', z:'a' },
#=>  { x:1, y:'b', z:'b' },
#=>  { x:1, y:'b', z:'c' },
#=>  { x:1, y:'c', z:'a' },
#=>  { x:1, y:'c', z:'b' },
#=>  { x:1, y:'c', z:'c' }]

我可以找到需要更换的 key :

wildkeys = hash.select{ |k,v| v.nil? }.map(&:first)
#=> [:y, :z] 

因此我可以 find all the permutations of values needed :

wildvalues = values.repeated_permutation( wildkeys.length ).to_a
#=> [["a", "a"], ["a", "b"], ["a", "c"], ["b", "a"],
#=>  ["b", "b"], ["b", "c"], ["c", "a"], ["c", "b"], ["c", "c"]] 

但是我想不出一个简单的方法来将这两个合并到原来的。

最佳答案

可能是这样的:

rest = hash.reject { |k,v| v.nil? }.to_a
wildvalues.map { |wv| Hash[rest + wildkeys.zip(wv)] }

甚至

wildvalues.map { |wv| hash.merge(Hash[wildkeys.zip(wv)]) }

关于ruby - 用每个可能的值填充散列中的通配符值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21352443/

相关文章:

ruby - 安装 nokogiri 错误 : unrecognized command line option "-Wdivision-by-zero"

ruby-on-rails - attr_accessible 在 Rails 中如何工作?

ruby-on-rails - 未定义方法 'zero' ... ActiveSupport::OrderedHash

Haskell - 集合的笛卡尔函数实现为二叉树

java - 使用带有未知数量参数的 guava Sets.cartesianProduct

ruby - 为什么 HANK 抛出编码问题而 ERB 和 ERUBY 不抛出

ruby - 尝试使用 Blowfish 解密数据时出现 NoMethodError

php - 制作多个数组的每个组合,而不重复每个数组中的项目

haskell - Haskell 中的惰性笛卡尔积

python - Python 中的笛卡尔积通用函数