How to subtract two consecutive element in a list in Scala?

You do not mutability nor imperative programming to solve this problem, functional programming got you covered.

def consecutiveDifferences(data: List[Int]): List[Int] =
  if (data.isEmpty) List.empty
  else data.lazyZip(data.tail).map {
    case (x, y) => y - x
 }

As I always say, the Scaladoc is your friend.
(Also, as an advice, the best way to learn functional programming is to forbid yourself from mutability)


You can use the sliding method, which according to the docs:

/** Groups elements in fixed size blocks by passing a "sliding window"
 *  over them (as opposed to partitioning them, as is done in `grouped`.)
 *
 *  An empty collection returns an empty iterator, and a non-empty
 *  collection containing fewer elements than the window size returns
 *  an iterator that will produce the original collection as its only
 *  element.
 *  @see [[scala.collection.Iterator]], method `sliding`
 *
 *  @param size the number of elements per group
 *  @return An iterator producing ${coll}s of size `size`, except for a
 *          non-empty collection with less than `size` elements, which
 *          returns an iterator that produces the source collection itself
 *          as its only element.
 *  @example `List().sliding(2) = empty iterator`
 *  @example `List(1).sliding(2) = Iterator(List(1))`
 *  @example `List(1, 2).sliding(2) = Iterator(List(1, 2))`
 *  @example `List(1, 2, 3).sliding(2) = Iterator(List(1, 2), List(2, 3))`
 */

Then, solving your query is pretty straight forward:

diffList = sortedList.sliding(2).collect {
  case Seq(a, b) =>
    b - a
}.toList

Which results in List(1,1)

Code run at Scastie.


for(i <- 0 until (sortedList.size - 1)) yield sortedList(i + 1) - sortedList(i)

yield Vector(1,1) which can be converted to list with toList

That's can be also achieved with the following function:

  val sortedList = List(4,5,7)
  @tailrec
  def findDiffs(xs: List[Int])(seed: List[Int]): List[Int] = {
    if(xs.isEmpty || xs.size == 1) seed.reverse
    else {
      val currDiff = xs(1) - xs(0)
      findDiffs(xs.tail)(currDiff :: seed)
    }
  }
  val res = findDiffs(sortedList)(Nil)
  println(res)

Or just easily with zip:

sortedList.drop(1) zip sortedList map { case (x,y) => x - y } 

Tags:

List

Scala