如何在ruby中组合/排列?

我有这个熟悉的问题,看起来像数学世界的排列/组合。

如何通过ruby实现以下function?

badges = "1-2-3" badge_cascade = [] badges.split("-").each do |b| badge_cascade < ["1", "2", "3"] But I want it to be is: => ["1", "2", "3", "1-2", "2-3", "3-1", "2-1", "3-2", "1-3", "1-2-3", "2-3-1", "3-1-2"] 

function方法:

 bs = "1-2-3".split("-") strings = 1.upto(bs.size).flat_map do |n| bs.permutation(n).map { |vs| vs.join("-") } end #=> ["1", "2", "3", "1-2", "1-3", "2-1", "2-3", "3-1", "3-2", "1-2-3", "1-3-2", "2-1-3", "2-3-1", "3-1-2", "3-2-1"] 

您需要使用Array#permutation方法来获取所有排列:

 arr = "1-2-3".split '-' # => ["1", "2", "3"] res = (1..arr.length).reduce([]) { |res, length| res += arr.permutation(length).to_a }.map {|arr| arr.join('-')} puts res.inspect # => ["1", "2", "3", "1-2", "1-3", "2-1", "2-3", "3-1", "3-2", "1-2-3", "1-3-2", "2-1-3", "2-3-1", "3-1-2", "3-2-1"] 

让我解释一下代码:

  1. 您将字符串拆分为数组,将分隔符'-'传递给String#split方法

  2. 您需要长度为1,2,3的所有排列。范围1..arr.length表示所有这些长度。

  3. 您使用Enumerable #reduce收集所有排列的数组。 您将在此处获得数组:

     [["1"], ["2"], ["3"], ["1", "2"], ["1", "3"], ["2", "1"], ["2", "3"], ["3", "1"], ["3", "2"], ["1", "2", "3"], ["1", "3", "2"], ["2", "1", "3"], ["2", "3", "1"], ["3", "1", "2"], ["3", "2", "1"]] 
  4. 您可以使用Array#join将此数组的所有子数组转换为字符串,并使用Enumerable #map中的 '-'分隔符

Array#permutation(n)将为Array#permutation(n)提供长度为n的所有排列,因此您可以使用1和徽章中的位数之间的每个长度来调用它。 最后一步是将这些全部映射回用-分隔的字符串。

 badges = "1-2-3" badges_split = badges.split('-') permutations = [] (1..badges_split.size).each do |n| permutations += badges_split.permutation(n).to_a end result = permutations.map { |permutation| permutation.join('-') } 

更新: 我认为Alex使用reduce是一种更优雅的方法,但我现在将这个答案保留在这里,以防它有用。