Detect consecutive elements in a list

if you don’t want to use the stdlib method containsSlice (so list.containsSlice(List(a, b))) how about

val a: A
val b: A

def containsab(list: List[A]) = list match {
  case `a` :: `b` :: _ => true
  case  _ :: tail => containsab(tail)
  case _ => false
}

If you want to make your own containsSlice with combinators

def containsSlice[A](list: List[A], sublist: List[A]) = {
  list.sliding(toFind.length).contains(toFind)
  //or, more efficiently list.iterator.sliding(toFind.length).exists(it => it.sameElements(sublist))
}

or if you want to write out the recursion by hand

def containsSlice[A](list: List[A], sublist: List[A]) = list.startsWith(sublist) ||
  list.tailOption match {
    case Some(tail) => containsSlice(tail)
    case None => false
  }

the prettier

def containsSlice[A](list: List[A], sublist: List[A]) = list.startsWith(sublist)
  || list.tailOption.map(t => containsSlice(t, sublist)).getOrElse(false)

won’t work as the recursive call is inside the map, it won’t optimize out.

the “use unsafe methods for performance” version would be

def containsSlice[A](list: List[A], sublist: List[A]) = list.startsWith(sublist) ||
  list.nonEmpty && containsSlice(list.tail)
2 Likes