views:

59

answers:

2

Given an array of strings

["the" "cat" "sat" "on" "the" "mat"]

I'm looking to get all combinations of items in sequence, from any starting position, e.g.

["the"]
["the" "cat"]
["the" "cat" "sat"]
...
["cat" "sat" "on" "the" "mat"]
["sat" "on" "the" "mat"]
["on" "the" "mat"]
...
["sat" "on"]
["sat" "on" "the"]

Combinations out of the original sequence or with missing elements are disallowed, e.g.

["sat" "mat"] # missing "on"
["the" "on"]  # reverse order

I'd also like to know if this operation has a particular name or if there's a neater way of describing it.

Thanks.

+3  A: 

Just iterate over each starting position and for each starting position over each possible end position:

arr = ["the", "cat", "sat", "on", "the", "mat"]
(0 ... arr.length).map do |i|
  (i ... arr.length).map do |j|
    arr[i..j]
  end
end.flatten(1)
#=> [["the"], ["the", "cat"], ["the", "cat", "sat"], ["the", "cat", "sat", "on"], ["the", "cat", "sat", "on", "the"], ["the", "cat", "sat", "on", "the", "mat"], ["cat"], ["cat", "sat"], ["cat", "sat", "on"], ["cat", "sat", "on", "the"], ["cat", "sat", "on", "the", "mat"], ["sat"], ["sat", "on"], ["sat", "on", "the"], ["sat", "on", "the", "mat"], ["on"], ["on", "the"], ["on", "the", "mat"], ["the"], ["the", "mat"], ["mat"]]

Requires ruby 1.8.7+ (or backports) for flatten(1).

sepp2k
I took the liberty of editing the ranges to use `...` instead of `-1`. Also note that Ruby 1.9.2 introduces `flat_map` which is basically equivalent to `map{}.flatten(1)`. Also available with `backports` :-)
Marc-André Lafortune
+2  A: 

If you're into one-liners, you might try

(0..arr.length).to_a.combination(2).map{|i,j| arr[i...j]}

BTW, I think those are called "all subsequences" of an array.

Mladen Jablanović
He's asking about substrings, not subsequences. Every substring is also a subsequence, but not all subsequences are substrings. For example, `235` is a subsequence of `123456` but not a substring.
Jörg W Mittag
Thanks, I didn't know about the difference. So, substrings need to be consecutive elements in the original array, while subsequences don't.
Mladen Jablanović