Sliding


#1

Would it be possible to implement a sliding method like in Scala, so that the type of collection is kept?

Examples

scala> Array(1, 2, 3, 4, 5).sliding(2).toList
res3: List[Array[Int]] = List(Array(1, 2), Array(2, 3), Array(3, 4), Array(4, 5))




scala> Set(1, 2, 3, 4, 5).sliding(2).toList
res0: List[scala.collection.immutable.Set[Int]] = List(Set(5, 1), Set(1, 2), Set(2, 3), Set(3, 4))

scala> List(1, 2, 3, 4, 5).sliding(2).toList
res1: List[List[Int]] = List(List(1, 2), List(2, 3), List(3, 4), List(4, 5))

I think it wouldn’t be possible, because the Sequence type doesn’t carry the information of the collection type, but only the type of the contained elements.


#2

Rx has a sliding window called `buffer`:

Observable.just(1, 2, 3, 4, 5)   .buffer(3, 1)   .subscribe { println("Received ${it}")

prints:

[main] Received [1, 2, 3] [main] Received [2, 3, 4] [main] Received [3, 4, 5] [main] Received [4, 5] [main] Received [5]


#3

The topic title is a bit misleading but Christian talks about retaining the Monad type, not so much about sliding functionality. I think it really helps Christian if you have an idea how this should work in byte/java code, as to retain interopability with Java.


#4

To avoid adding an external dependency, you could also define a small extension function:

fun <T> List<T>.sliding(windowSize: Int): List<List<T>> {
    return this.dropLast(windowSize - 1).mapIndexed { i, s -> this.subList(i, i + windowSize) }
}
// Example Usage
val data = arrayListOf("a", "b", "c", "d")
val joinWindows = data.sliding(2).map { list -> list.joinToString(" ") }
print(joinWindows)

However, I’d also prefer such basic tools to be in the kotlin standard library.