The method sliding on collections returns a sliding window of given size in the form of X[Iterable[A]]
with X being the type of the collection and A the element type. Often I need two or three elements and I prefer to have them named. One ugly workaround for sliding(2)
is the following:
points.sliding(2).foreach{ twoPoints =>
val (p1,p2) = (twoPoints.head,twoPoints.last)
//do something
}
This sucks and only works for two elements. Also note that
(a,b) = (twoPoints(0),twoPoints(1))
doesn't work.
I recently wanted a little more sugar in my sliding iterators, so I came up with this:
implicit class SlidingOps[A](s: Seq[A]) {
def slidingPairs = (s, s.tail).zipped
def slidingTriples = (s, s.tail, s.tail.tail).zipped
}
This works with any Seq
, but is probably most efficient with List
. .zipped
returns a scala.runtime.Tuple2Zipped
(or Tuple3Zipped
for a 3-element tuple) object, which defines several familiar higher-order methods so that their arguments take multiple arguments, so you can write:
points.slidingPairs.foreach { (a, b) => ... }
or even:
(1 to 10).slidingTriples.map(_ + _ + _)
You can optimize the implementation further if you want it to be really efficient for non-list types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With