2010-08-16 99 views
0

对于我的第一个问题,我想问你如何在Ruby中执行以下操作。在Ruby中操作哈希和数组

我有以下方面

variables["foo"] = [1,2,3] 
variables["bar"] = [4,5,6,7] 
variables[...] = ... 

更新散列:该散列将具有键的任意数量=>值对。

所以它代表参数及其可能的值。我想现在“生成”一个包含哈希值的数组,其中键=>值对表示变量的每种可能组合。在上述示例的情况下,我将具有12(= 3×4)的阵列散列那样

[ hash1, hash2, ..., hash16] 

其中散列将是

hash1["foo"] = 1 
hash1["bar"] = 4 
hash2["foo"] = 1 
hash2["bar"] = 5 
hash3["foo"] = 1 
hash3["bar"] = 6 
hash4["foo"] = 1 
hash4["bar"] = 7 
hash5["foo"] = 2 
hash5["bar"] = 4 
hash6["foo"] = 3 
hash6["bar"] = 4 
... 
hash16["foo"] = 3 
hash16["bar"] = 7 

我有几个想法,但所有其中有相当复杂的嵌套环...

非常感谢!

+0

不应该hash2 [“foo”] = 2? – corroded 2010-08-16 10:39:34

+0

我想先得到第一个变量的第一个值和第二个值的每个值,然后是第一个变量的第二个值和第二个值的每个值,等等。 – 2010-08-16 12:27:39

回答

1
vars = {foo: [1, 2, 3], bar: [4, 5, 6, 7]} 

(v = vars.map {|k, v| ([k] * v.length).zip(v) }).first.product(*v.drop(1)). 
map {|args| args.reduce({}) {|h, (k, v)| h.tap {|h| h[k] = v }}} 
# => [{:foo=>1, :bar=>4}, 
# => {:foo=>1, :bar=>5}, 
# => {:foo=>1, :bar=>6}, 
# => {:foo=>1, :bar=>7}, 
# => {:foo=>2, :bar=>4}, 
# => {:foo=>2, :bar=>5}, 
# => {:foo=>2, :bar=>6}, 
# => {:foo=>2, :bar=>7}, 
# => {:foo=>3, :bar=>4}, 
# => {:foo=>3, :bar=>5}, 
# => {:foo=>3, :bar=>6}, 
# => {:foo=>3, :bar=>7}] 

这适用于任意许多条目和任意键。

+0

非常感谢!我仍然需要完全理解它,但它按照我的意愿工作。 – 2010-08-16 13:48:54

1

数组的Ruby语法是括号,而对于散列,则是用一个键,哈希值=>的大括号。

variables = { "foo" => [1,2,3] , "bar" => [4,5,6,7] } 

results = Array.new 

variables["foo"].each do |foo_variable| 
    variables["bar"].each do |bar_variable| 
    results << { "foo" => foo_variable , "bar" => bar_variable } 
    end 
end 

require "pp" 
pp results 
+0

谢谢。但我忘了说“变量”哈希有任意数量的条目。 – 2010-08-16 13:29:39

1
vars.values.inject(&:product).map{|values| 
    Hash[vars.keys.zip(values.flatten)] 
} 
+0

这真的很不错。我在类似的东西周围玩,但是我在语言规范中找不到任何能确保'Hash#keys'和'Hash#values'以相同顺序返回项目的东西,所以我退出了它。但是现在我意识到我无论如何都使用了1.9个功能,而在1.9中,'Hash'当然可以保证无论如何都是有序的,所以假设你在1.9上运行它,你的解决方案会更好。 – 2010-08-17 00:39:02