Reck Reck - 3 months ago 10
Ruby Question

idiomatic way to check if array contains ordered (but possibly non-continuous) set of elements

I was wondering if there is a more idiomatic way to get the functionality represented by the code below. Basically I just want to check if the array contains the elements in

pattern
in the order specified by
pattern
. It's okay for there to be gaps between these elements.

class Array
def has_pattern?(pattern)
offset = 0
pattern.each do |p|
offset = self[offset..-1].index(p)
return false if offset.nil?
end
return true
end
end

puts [1, 2, 3, 4, 5, 1].has_pattern?([1, 4, 5]) # true
puts [1, 2, 3, 4, 5, 1].has_pattern?([2, 3, 1]) # true
puts [1, 2, 3, 4, 5, 1].has_pattern?([1, 3, 2]) # false


The code above seems to work, but doesn't feel like idiomatic Ruby to me. Is there a nicer way to write this?

Answer

Here's my take on it:

class Array
  def has_pattern?(ptn)
    i = 0
    self.each do |elem|
      i += 1 if elem == ptn[i]
    end
    i >= ptn.size
  end
end

It passes through the array only once, so it may make a difference when the array's big.