Testing for subarrays

I want to check whether a given array contains a given subarray and
return the corresponding range.
Is there a builtin method ? If not, do you have better than this :

class Array
def look_up(sub_array)
len = sub_array.size
self.each_cons(len).with_index do |cons, index|
return Range.new(index, index + len - 1) if cons == sub_array
end
nil
end
end

_md

On Mon, Oct 11, 2010 at 11:27 AM, Michel D. [email protected]
wrote:

nil
end
end

Not necessarily better:

irb(main):001:0> a = [1,2,3,4,5,6,7,8]
=> [1, 2, 3, 4, 5, 6, 7, 8]
irb(main):002:0> b = [4,5,6]
=> [4, 5, 6]
irb(main):004:0> a.each_cons(b.size).to_a.index(b)
=> 3
irb(main):005:0> a.each_cons(b.size).to_a.index([5,1,2])
=> nil

Jesus.

Jesús Gabriel y Galán wrote:

a.each_cons(b.size).to_a.index(b)

Yes !
_md

Hi –

On Mon, 11 Oct 2010, Jesús Gabriel y Galán wrote:

  end
irb(main):004:0> a.each_cons(b.size).to_a.index(b)
=> 3
irb(main):005:0> a.each_cons(b.size).to_a.index([5,1,2])
=> nil

Here’s another way that is more verbose but that doesn’t create the
whole array (which probably doesn’t matter anyway, unless it’s a huge
array and you’re cycle-shaving). I also prefer extending individual
objects, rather than adding to Array.

module SubArrayFinder
def look_up(sub_array)
sub_size = sub_array.size
index = find_index.with_index do |e,i|
self[i, sub_size] == sub_array
end
return(index…index+sub_size-1) if index
end
end

David


David A. Black, Senior Developer, Cyrus Innovation Inc.

The Ruby training with Black/Brown/McAnally
Compleat Philadelphia, PA, October 1-2, 2010
Rubyist http://www.compleatrubyist.com

Michel D. wrote:

Comparing with my original proposal, a side question is whether using
each_cons is faster, or not, that iterating with self[i, sub_size]…

_md

sub(“that”, “than”), sorry
_md

David A. Black wrote:

Here’s another way that is more verbose but that doesn’t create the
whole array (which probably doesn’t matter anyway, unless it’s a huge
array and you’re cycle-shaving). I also prefer extending individual
objects, rather than adding to Array.

module SubArrayFinder
def look_up(sub_array)
sub_size = sub_array.size
index = find_index.with_index do |e,i|
self[i, sub_size] == sub_array
end
return(index…index+sub_size-1) if index
end
end

Comparing with my original proposal, a side question is whether using
each_cons is faster, or not, that iterating with self[i, sub_size]…

_md