Ruby字符串/数组组合保留顺序

时间:2017-03-01 04:00:01

标签: ruby

我想找到保留订单的字符串的所有组合。 Ruby中有没有内置的方法来实现这个目标?

例如,"abcd".all_combinations应该给出输出:

a
b
c
d
ab
bc
cd
abc
bcd
abcd

3 个答案:

答案 0 :(得分:3)

可能不是理想的实现,但这有效:

def combinations(str)
  items = str.chars
  (1..items.length).map { |i| items.each_cons(i).map(&:join) }.flatten
end

同时检查Enumerable#each_cons。您也可以将它添加到String类中,如下所示:

class String
  def combinations
    items = self.chars
    (1..items.length).map { |i| items.each_cons(i).map(&:join) }.flatten
  end
end

'abcd'.combinations

发生了什么:

  • 我们将字符串设为String#chars的实际字符数组。
  • 然后对于每个数字i介于1到字符串的长度之间:
    • 调用Enumerable#each_cons,它基本上返回长度为i的可能组合作为字符数组。因此,如果i为2,那么items.each_cons(2)的结果将为[ ['a', 'b'], ['b', 'c'], ['c', 'd'] ]
    • .map(&:join)部分基本上在该数组数组的每个元素上调用Array#join,因此它变为['ab', 'bc', 'cd']
  • (1..items.length).map { |i| items.each_cons(i).map(&:join) }的结果是:[ ['a', 'b', 'c', 'd'], ['ab', 'bc', 'cd'], ['abc', 'bcd'], ['abcd'] ]这是一个数组数组。我们在其上调用Array#flatten使其成为一个简单的数组(阅读flatten链接以获取更多信息)。

答案 1 :(得分:1)

没有内置功能可以完全满足您的需求。

String#each_cons看起来很有趣,正如Tamer指出的那样。

这是另一种解决方案:

def all_combos(str)
  1.upto(str.length) do |segment_length|
    0.upto(str.length - segment_length) do |starting_point|
      puts str[starting_point, segment_length]
    end
  end
end

all_combos("abcd")

答案 2 :(得分:1)

子字符串的起始和结束索引形成组合与重复的模式,Ruby确实有内置方法。

class String
  def all_combinations
    idx = (0 ... self.size).to_a
    idx.repeated_combination(2){|i,j| yield self[i..j]}
  end
end

"abcd".all_combinations{|combo| puts combo}