lib/nrser/ext/enumerable/slice.rb
# Test slice inclusion when both the `slice` and the `enum` that we're
# going to look for it in support `#length` and `#slice`
# in the same manner that {Array} does (hence the name).
# 
# This is much simpler and more efficient than the "general" {Enumerable}
# case where we can't necessarily find out how many entries are in the
# enumerables or really do much of anything with them except iterate through
# (at least, with my current grasp of {Enumerable} and {Enumerator} it
# seems painfully complex... in fact it may never terminate for infinite
# enumerables).
# 
# @param [Enumerable<E> & #length & #slice] enum
#   The {Enumerable} that we want test for `slice` inclusion. Must
#   support `#length` and `#slice` like {Array} does.
# 
# @param [Enumerable<S> & #length & #slice] slice
#   The {Enumerable} slice that we want to see if `enum` includes. Must
#   support `#length` and `#slice` like {Array} does.
# 
# @param [Proc<(E, S)=>Boolean>] is_match
#   Optional {Proc} that accepts an entry from `enum` and an entry from
#   `slice` and returns if they match.
# 
# @return [Boolean]
#   `true` if there is a slice of `enum` for which each entry matches the
#   corresponding entry in `slice` according to `&is_match`.
# 


This is much simpler and more efficient than the "general" {Enumerable}
case where we can't necessarily find out how many entries are in the
enumerables or really do much of anything with them except iterate through
(at least, with my current grasp of {Enumerable} and {Enumerator} it
seems painfully complex... in fact it may never terminate for infinite
enumerables).
This is much simpler and more efficient than the " general " { Enumerable } case where we can ' t necessarily find out how many entries are in the enumerables or really do much of anything with them except iterate through ( at least with my current grasp of { Enumerable } and { Enumerator } it seems painfully complex ... in fact it may never terminate for infinite enumerables ) .
def array_slice? slice, &is_match
    slice_length = slice.length
    return true if slice_length == 0
    length = self.length
    return false if slice_length > length
    if is_match.nil?
      is_match = ->(self_entry, slice_entry) {
        self_entry == slice_entry
      }
    end
    each_with_index do |self_entry, self_start_index|
      self_end_index = self_start_index + slice_length - 1
      return false if self_end_index >= length
      self_slice = self[self_start_index..self_end_index]
      return true if self_slice.zip( slice ).all? { |(self_entry, slice_entry)|
        is_match.call self_entry, slice_entry
      }
       until the number of `enum` entries left is too few for `slice`
    end
    So, we don't have a match.
    false
  end
def array_slice? slice , & is_match slice_length = slice . length return true if slice_length == 0 length = self . length return false if slice_length > length if is_match . nil? is_match = -> ( self_entry , slice_entry ) { self_entry == slice_entry } end each_with_index do | self_entry , self_start_index | self_end_index = self_start_index + slice_length - 1 return false if self_end_index >= length self_slice = self [ self_start_index .. self_end_index ] return true if self_slice . zip ( slice ) . all? { | ( self_entry , slice_entry ) | is_match . call self_entry , slice_entry } end false end
Test slice inclusion when both the `slice` and the `enum` that we're
going to look for it in support `#length` and `#slice`
in the same manner that {Array} does (hence the name).
Test slice inclusion when both the ` slice ` and the ` enum ` that we ' re going to look for it in support ` #length ` and ` #slice ` in the same manner that { Array } does ( hence the name ) .
# Short-circuit on empty slice - it's *always* present # Short-circuit if slice is longer than enum since we can't possibly # match # Create a default `#==` matcher if we weren't provided one. # Compute index in `self` that we would need to match up to # Short-circuit if can't match (more slice entries than enum ones left) # Create the slice to test against # See if every entry in the slice from `self` matches the corresponding # one in `slice` # Otherwise, just continue on through `enum` looking for that first # match until the number of `enum` entries left is too few for `slice` # to possibly match # We never matched the first `slice` entry to a `enum` entry (and `slice` # had to be of length 1 so that the "too long" short-circuit never fired). #  # So, we don't have a match.
`true` if there is a slice of `enum` for which each entry matches the corresponding entry in `slice` according to `&is_match`.
` true ` if there is a slice of ` enum ` for which each entry matches the corresponding entry in ` slice ` according to ` &is_match ` .
Boolean
slice
<not_specific>
is_match
<not_specific>
<not_specific>
is_match Optional {Proc} that accepts an entry from `enum` and an entry from `slice` and returns if they match.
is_match Optional { Proc } that accepts an entry from ` enum ` and an entry from ` slice ` and returns if they match .