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

···

--
Posted via http://www.ruby-forum.com/.

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.

···

On Mon, Oct 11, 2010 at 11:27 AM, Michel Demazure <michel@demazure.com> wrote:

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

Jesús Gabriel y Galán wrote:

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

Yes !
_md

···

--
Posted via http://www.ruby-forum.com/\.

Hi --

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

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

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

···

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

On Mon, Oct 11, 2010 at 11:27 AM, Michel Demazure <michel@demazure.com> wrote:

--
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

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

···

--
Posted via http://www.ruby-forum.com/\.

Michel Demazure 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

···

--
Posted via http://www.ruby-forum.com/\.