Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Output of Iterable.sliding as Tuple

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.

like image 312
ziggystar Avatar asked Jan 17 '11 20:01

ziggystar


1 Answers

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.

like image 132
Brian McCutchon Avatar answered Dec 09 '22 05:12

Brian McCutchon