I have problems with writing an specific application in a scala-esque and elegant way. I tried this for some time now, but I cannot find a "good" solution to this Problem:
Given that I have the following List:
List("foo", "bar", "baz", "blah")
I want to Iterate over this list, not only giving me the current element for each Iteration but also the element before and after the current element. This might be a Tuple3 but is not required to. This could be the Tuple signature:
(Option[T], T, Option[T])
To clarify what i mean, this is the proposed Tuple for each iteration over a List[String]
, ending after the fourth.
Iteration 1: (None, "foo", Some("bar"))
Iteration 2: (Some("foo"), "bar", Some("baz"))
Iteration 3: (Some("bar"), "baz", Some("blah"))
Iteration 4: (Some("baz"), "blah", None)
How could I achieve such a result? Again: I am not bound to the Tuple3, any other solution is also very appreciated!
Thanks!
Here's one approach. It uses a new Scala 2.8 collection method sliding
.
def window[A](l: List[A]): Iterator[List[Option[A]]] =
(None :: l.map(Some(_)) ::: List(None)) sliding 3
window(List(1, 2, 3, 4, 5)).toList
// List(List(None, Some(1), Some(2)), List(Some(1), Some(2), Some(3)), List(Some(2), Some(3), Some(4)), List(Some(3), Some(4), Some(5)), List(Some(4), Some(5), None))
Update: Heres a version that works for Streams.
def windowS[A](s: Stream[A]): Stream[List[Option[A]]] =
(None #:: s.map(Some(_): Option[A]) #::: Stream(None: Option[A])).sliding(3).toStream.map(_.toList)
val posInts = Stream.range(1, Integer.MAX_VALUE)
windowS(posInts).take(5).toList
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