Checking if a given integer element in all the tuples contained in the collection is in consecutive order

Viewed 58

Having a collection of tuples I would like to check if a given integer element in all the tuples is having values in consecutive order. For simplicity it can be assumed that the tuples are sorted in ascending order by that element.

For example considering the first element of all tuples in this array should return false (4, 8, 9, 10, 13):

val a = List((4,2), (8,1), (9,4), (10,2), (13,1))

While considering the first element of all the tuples in this array should return true (8, 9, 10, 11, 12):

val b = List((8,2), (9,1), (10,4), (11,2), (12,1))

Using List as a collection with pattern matching I can do the check using the pattern matching as presented below:

def consecutive(l: List[(Int, Int)], last: Option[Int] = Option.empty): Boolean =
  l match {
    case h :: t => {
      if (last.isEmpty || (last.isDefined && h._1 == last.get + 1))
        consecutive(t, Option(h._1))
      else false
    }
    case Nil => true
  }

Is there an easier way to accomplish it?

2 Answers

Here is what you can try using sliding:

def consecutive(s: Seq[(Int, Int)]): Boolean = s match {
      case Seq() => true
      case Seq(_) => true
      case _ => s.sliding(2).forall { case Seq((x, _), (y, _)) =>  x + 1 == y }
  }

scala>consecutive(b)
res5: Boolean = true

consecutive(a)
res7: Boolean = false

or you can try this definition as well:

def consecutive(s: Seq[(Int, Int)]): Boolean = 
   if (s.isEmpty) true
   else (s zip s.tail) forall { case ((x,_), (y,_)) => x + 1 == y} 

Here is a solution using foldLeft

def consecutive(list: List[(Int, Int)]): Boolean = {
  list.map(_._1) match {
    case first :: second :: tail =>
      val (_, isConsecutive) =
        (second :: tail).foldLeft((first, true)) { case ((previous, previousWasConsecutive), next) =>
          (next, next - previous == 1 && previousWasConsecutive)
        }
      isConsecutive

    case _ => true
  }
}

which outputs

consecutive(Nil)                                        // res0: Boolean = true
consecutive(List((1,2)))                                // res1: Boolean = true
consecutive(List((4,2), (8,1), (9,4), (10,2), (13,1)))  // res2: Boolean = false
consecutive(List((8,2), (9,1), (10,4), (11,2), (12,1))) // res3: Boolean = true
Related