Reputation: 6460
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
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
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
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