将数组转换为某些数组

Dou*_*oug 3 ruby arrays algorithm ruby-1.9.3

我想将Ruby数组(可能包含一些子数组)扩展到另一个数组数组中,就像在这些示例中一样:

例1: [:foo, :bar]

[
  [:foo, :bar]
]
Run Code Online (Sandbox Code Playgroud)

例2: [:foo, :bar, [:ki, :ku]]

[
  [:foo, :bar, :ki],
  [:foo, :bar, :ku]
]
Run Code Online (Sandbox Code Playgroud)

例3: [:foo, :bar, :baz, [:a, :i, :u, :e, :o], :qux]

[
  [:foo, :bar, :baz, :a, :qux],
  [:foo, :bar, :baz, :i, :qux],
  [:foo, :bar, :baz, :u, :qux],
  [:foo, :bar, :baz, :e, :qux],
  [:foo, :bar, :baz, :o, :qux]
]
Run Code Online (Sandbox Code Playgroud)

例4: [:foo, :bar, :baz, [:a, :i, :u, :e, :o], [1, 2], :qux]

[
  [:foo, :bar, :baz, :a, 1, :qux],
  [:foo, :bar, :baz, :i, 1, :qux],
  [:foo, :bar, :baz, :u, 1, :qux],
  [:foo, :bar, :baz, :e, 1, :qux],
  [:foo, :bar, :baz, :o, 1, :qux],
  [:foo, :bar, :baz, :a, 2, :qux],
  [:foo, :bar, :baz, :i, 2, :qux],
  [:foo, :bar, :baz, :u, 2, :qux],
  [:foo, :bar, :baz, :e, 2, :qux],
  [:foo, :bar, :baz, :o, 2, :qux]
]
Run Code Online (Sandbox Code Playgroud)

例5: [:foo, [[], :c], :bar]

[
  [:foo, [], :bar],
  [:foo, :c, :bar]
]
Run Code Online (Sandbox Code Playgroud)

例6: [:foo, [[:a, :b], :c], :bar]

[
  [:foo, [:a, :b], :bar],
  [:foo, :c, :bar]
]
Run Code Online (Sandbox Code Playgroud)

注意:只应扩展子数组.这就是为什么在示例5和6中,不扩展子子阵列的原因.

非常感谢任何建议或代码.

Adi*_*ann 8

我用这个product想法来实现这个功能:

def trans(a)
  b = a.map{|e| [e].flatten(1)}
  b.first.product(*b.slice(1..-1))
end
Run Code Online (Sandbox Code Playgroud)

例如,这段代码:

puts trans([:foo, :bar]).inspect
puts trans([:foo, :bar, :baz, [:a, :i, :u, :e, :o], [1, 2], :qux]).inspect
puts trans([:foo, [[], :c], :bar]).inspect
puts trans([:foo, [[:a, :b], :c], :bar]).inspect
Run Code Online (Sandbox Code Playgroud)

给出这个:

[[:foo, :bar]]
[[:foo, :bar, :baz, :a, 1, :qux],
 [:foo, :bar, :baz, :a, 2, :qux],
 [:foo, :bar, :baz, :i, 1, :qux],
 [:foo, :bar, :baz, :i, 2, :qux],
 [:foo, :bar, :baz, :u, 1, :qux],
 [:foo, :bar, :baz, :u, 2, :qux],
 [:foo, :bar, :baz, :e, 1, :qux],
 [:foo, :bar, :baz, :e, 2, :qux],
 [:foo, :bar, :baz, :o, 1, :qux],
 [:foo, :bar, :baz, :o, 2, :qux]]
[[:foo, [], :bar],
 [:foo, :c, :bar]]
[[:foo, [:a, :b], :bar],
 [:foo, :c, :bar]]
Run Code Online (Sandbox Code Playgroud)

编辑:上述代码的解释.

一般的想法是,我们要在阵列中的所有元素的产品.如果你看一下Array#产品的文档,你会发现它做了你想要的 - 我们只需要适当地调用它.

首先,product对数组进行操作,因此我们必须确保原始数组中的所有项都是数组.这是函数第一行的任务:

b = a.map{|e| [e].flatten(1)}
Run Code Online (Sandbox Code Playgroud)

我们正在使用转换数组中的所有元素map.转换生成一个包含元素的数组e,然后展平这个新数组.原始元素是数组还是不是; 如果它不是一个数组,[e].flatten(1)将什么也不做,将返回[e]; 如果它是一个数组,[e]将评估为[[x]],然后将其展平为[x].该1通知flatten去只有1级深.

然后我们要做的就是调用product第一个元素作为参数传递修改后的数组的其余元素:

b.first.product(*b.slice(1..-1))
Run Code Online (Sandbox Code Playgroud)

这里,b.slice(1..-1)意思是:从第二个一直到最后一个从b获取元素.最后,星号表示我们不想将数组作为参数传递,而是传递数组的元素.