0

我正在尝试编写一个执行以下操作的Array扩展:

我这样称呼它:

%w[eggs bacon sausage].with_every_possibiity_of_multiples(2)

它给了我这些:

  [   
    %w[eggs, bacon, sausage],
    %w[eggs, eggs, bacon, sausage],
    %w[eggs, bacon, bacon, sausage],
    %w[eggs, bacon, sausage, sausage],
    %w[eggs, eggs, bacon, bacon, sausage],
    %w[eggs, eggs, bacon, bacon, sausage, sausage],
  ]

希望很清楚这里发生了什么。如果我用 3 而不是 2 的参数调用它,我会得到一个由 9 个元素组成的数组,其中一个是%w[eggs, eggs, eggs, bacon, sausage].

我正在努力想出如何写这个。有什么建议么?

4

2 回答 2

1

正如@sawa 指出的那样,您的结果可能混淆了。我猜传递 2 得到 8 个元素,而不是 6,传递 3 得到 27,而不是 9。

您可以充分利用Array#repeated_combination来生成要重复每个元素的次数:

class Array
  def with_every_possibility_of_multiples(n)
    (1..n).to_a.repeated_permutation(size).map do |repeats|
      zip(repeats).flat_map{|elem, nb| [elem] * nb}
    end
  end
end

food = %w[eggs bacon sausage]
food.with_every_possibility_of_multiples(2) # =>
[["eggs", "bacon", "sausage"], ["eggs", "bacon", "sausage", "sausage"], ["eggs", "bacon", "bacon", "sausage"],
 ["eggs", "bacon", "bacon", "sausage", "sausage"],
 ["eggs", "eggs", "bacon", "sausage"],
 ["eggs", "eggs", "bacon", "sausage", "sausage"],
 ["eggs", "eggs", "bacon", "bacon", "sausage"],
 ["eggs", "eggs", "bacon", "bacon", "sausage", "sausage"]]

food.with_every_possibility_of_multiples(3) # =>
[["eggs", "bacon", "sausage"],
 ["eggs", "bacon", "sausage", "sausage"],
 ["eggs", "bacon", "sausage", "sausage", "sausage"],
 ["eggs", "bacon", "bacon", "sausage"],
 ["eggs", "bacon", "bacon", "sausage", "sausage"],
 ["eggs", "bacon", "bacon", "sausage", "sausage", "sausage"],
 ["eggs", "bacon", "bacon", "bacon", "sausage"],
 ["eggs", "bacon", "bacon", "bacon", "sausage", "sausage"],
 ["eggs", "bacon", "bacon", "bacon", "sausage", "sausage", "sausage"],
 ["eggs", "eggs", "bacon", "sausage"],
 ["eggs", "eggs", "bacon", "sausage", "sausage"],
 ["eggs", "eggs", "bacon", "sausage", "sausage", "sausage"],
 ["eggs", "eggs", "bacon", "bacon", "sausage"],
 ["eggs", "eggs", "bacon", "bacon", "sausage", "sausage"],
 ["eggs", "eggs", "bacon", "bacon", "sausage", "sausage", "sausage"],
 ["eggs", "eggs", "bacon", "bacon", "bacon", "sausage"],
 ["eggs", "eggs", "bacon", "bacon", "bacon", "sausage", "sausage"],
 ["eggs", "eggs", "bacon", "bacon", "bacon", "sausage", "sausage", "sausage"],
 ["eggs", "eggs", "eggs", "bacon", "sausage"],
 ["eggs", "eggs", "eggs", "bacon", "sausage", "sausage"],
 ["eggs", "eggs", "eggs", "bacon", "sausage", "sausage", "sausage"],
 ["eggs", "eggs", "eggs", "bacon", "bacon", "sausage"],
 ["eggs", "eggs", "eggs", "bacon", "bacon", "sausage", "sausage"],
 ["eggs", "eggs", "eggs", "bacon", "bacon", "sausage", "sausage", "sausage"],
 ["eggs", "eggs", "eggs", "bacon", "bacon", "bacon", "sausage"],
 ["eggs", "eggs", "eggs", "bacon", "bacon", "bacon", "sausage", "sausage"],
 ["eggs", "eggs", "eggs", "bacon", "bacon", "bacon", "sausage", "sausage", "sausage"]]

请注意,这repeated_permutation是 Ruby 1.9.2 的新内容。您可以require 'backports'在早期版本中,或使用更丑陋的版本product

# ...
(1..n).to_a.product(*[(1..n).to_a] * (size-1)).map do |repeats|
# ...
于 2012-11-27T03:43:43.657 回答
0

你可以试试这个内置的排列方法:

   %w[eggs bacon sausage].permutation(2).to_a
于 2012-11-27T03:35:09.697 回答