给定一个数组哈希,如何使用每个可能的组合创建一个哈希数组

时间:2018-10-10 20:53:27

标签: arrays ruby hash

给出一个散列,其值包含不等长数组,

{a: [1, 2, 3], b: [1, 2], c: [1]}

是否有可能创建一个包含相同键的散列数组,这些散列包含单个值的所有排列,如下所示,而无需借助嵌套多个循环?

[
  {a: 1, b: 1, c: 1},
  {a: 1, b: 2, c: 1},
  {a: 2, b: 1, c: 1},
  {a: 2, b: 2, c: 1},
  {a: 3, b: 2, c: 1},
  {a: 3, b: 2, c: 1}
]

我们为每个键使用嵌套的each循环来完成此操作,但这看起来很麻烦。实际数据包含更多键。

3 个答案:

答案 0 :(得分:6)

keys = hash.keys
hash.values.inject(:product).map do |p|
  Hash[keys.zip(p.flatten)]
end

答案 1 :(得分:2)

h = { a:[1,2,3], b:[1,2], c: [1] }

first, *rest = h.map { |k,v| [k].product(v) }
  #=> [[[:a, 1], [:a, 2], [:a, 3]], [[:b, 1], [:b, 2]], [[:c, 1]]]
first.product(*rest).map(&:to_h)
  #=> [{:a=>1, :b=>1, :c=>1}, {:a=>1, :b=>2, :c=>1}, {:a=>2, :b=>1, :c=>1},
  #    {:a=>2, :b=>2, :c=>1}, {:a=>3, :b=>1, :c=>1}, {:a=>3, :b=>2, :c=>1}]

请注意第二步的中间计算:

first.product(*rest)
  #=> [[[:a, 1], [:b, 1], [:c, 1]],
  #    [[:a, 1], [:b, 2], [:c, 1]],
  #    [[:a, 2], [:b, 1], [:c, 1]],
  #    [[:a, 2], [:b, 2], [:c, 1]],
  #    [[:a, 3], [:b, 1], [:c, 1]],
  #    [[:a, 3], [:b, 2], [:c, 1]]]

答案 2 :(得分:0)

有很多方法可以做到这一点。就个人而言,我喜欢@MarcinKołodziej解决方案的紧凑性和有效性,但是,对于新手来说,它似乎有些神秘。

解决该问题的另一种方法是手动遍历哈希并构建数组:

<AbsoluteLayout bottom="0">