Gavin
Gavin

Reputation: 6460

Get differences between members of a list

I have a list of values and want to reduce it to a list of differences between successive members. Is there a better way than this I have come up with (Trivial example) ?

val l1 = List(1,2,3,4,5,6)

val diffs = (l1 zip l1.drop(1)).map{case (x,y) => y - x}.sum

Upvotes: 3

Views: 1963

Answers (3)

Luigi Plinge
Luigi Plinge

Reputation: 51109

I'm sure I've answered a very similiar question before, but I can't find it. Anyway, try zipped as it's more efficient and gives nicer syntax:

(l1 drop 1, l1).zipped.map(_-_).sum

Upvotes: 9

tehlexx
tehlexx

Reputation: 2859

I like use sliding for this use-case:

val l1 = List(1,2,3,4,5,6)
val diffs = l1.sliding(2).map{case List(x, y) => x - y}.sum

Try it here.

Upvotes: 5

0__
0__

Reputation: 67290

You could use sliding

l1.sliding(2).map { case Seq(a, b) => b - a } .sum

But that's not much shorter. Also if you have a list, you could use l1.tail instead of l1.drop(1).

I have once written the following extension method:

import collection.generic.CanBuildFrom

implicit final class RichIterableLike[A, CC[~] <: Iterable[~]](val it: CC[A])
  extends AnyVal {
  def mapPairs[B, To](fun: (A,A)=>B)(implicit cbf: CanBuildFrom[CC[A], B, To]): To = {
    val b     = cbf(it)
    val iter  = it.iterator
    if (iter.hasNext) {
      var pred = iter.next()
      while (iter.hasNext) {
        val succ = iter.next()
        b += fun(pred, succ)
        pred = succ
      }
    }
    b.result()
  }
}

With that:

l1.mapPairs(-_+_).sum

Upvotes: 1

Related Questions