Add Sequence.peekable()
This commit is contained in:
parent
0aeab3a96b
commit
fafefc2820
|
@ -0,0 +1,37 @@
|
|||
package moe.kageru.sekwences
|
||||
|
||||
class PeekableSequence<T>(source: Sequence<T>) : Sequence<T> {
|
||||
private val iterator: PeekableIterator<T> = PeekableIterator(source.iterator())
|
||||
|
||||
override fun iterator(): Iterator<T> = iterator
|
||||
|
||||
fun peek(): T? = iterator.peek()
|
||||
}
|
||||
|
||||
internal class PeekableIterator<T>(private val source: Iterator<T>) : Iterator<T> {
|
||||
private var peeked: T? = null
|
||||
override fun hasNext(): Boolean {
|
||||
return source.hasNext() || peeked != null
|
||||
}
|
||||
|
||||
override fun next(): T {
|
||||
return if (peeked == null) {
|
||||
source.next()
|
||||
} else {
|
||||
val ret = peeked
|
||||
peeked = null
|
||||
ret!!
|
||||
}
|
||||
}
|
||||
|
||||
fun peek(): T? {
|
||||
return when {
|
||||
peeked != null -> peeked
|
||||
hasNext() -> {
|
||||
peeked = next()
|
||||
peeked!!
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,3 +18,12 @@ fun <T> Sequence<T>.coalesce(merger: (T, T) -> T?): Sequence<T> {
|
|||
emptySequence()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifies the current [Sequence] by adding a peek() method
|
||||
* that returns the next element or null without advancing the sequence.
|
||||
* Calling peek() multiple times without next() will return the same value.
|
||||
*/
|
||||
fun <T> Sequence<T>.peekable(): PeekableSequence<T> {
|
||||
return PeekableSequence(this)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package moe.kageru.sekwences
|
|||
import io.kotlintest.shouldBe
|
||||
import io.kotlintest.specs.ShouldSpec
|
||||
|
||||
class SekwencesTest : ShouldSpec({
|
||||
class CoalesceTest : ShouldSpec({
|
||||
"should merge numbers" {
|
||||
val input = sequenceOf(1, 2, 3, 4, 5, 6, 4)
|
||||
val output = input.coalesce { first, second ->
|
|
@ -0,0 +1,24 @@
|
|||
package moe.kageru.sekwences
|
||||
|
||||
import io.kotlintest.shouldBe
|
||||
import io.kotlintest.specs.ShouldSpec
|
||||
|
||||
class PeekableTest : ShouldSpec({
|
||||
"peek should return correct values" {
|
||||
val input = sequenceOf(1, 2, 3, 4).peekable()
|
||||
input.peek() shouldBe 1
|
||||
input.peek() shouldBe input.peek()
|
||||
input.iterator().next() shouldBe 1
|
||||
input.peek() shouldBe 2
|
||||
input.iterator().next() shouldBe 2
|
||||
input.iterator().next() shouldBe 3
|
||||
input.iterator().next() shouldBe 4
|
||||
input.peek() shouldBe null
|
||||
}
|
||||
|
||||
"sequence should operate normally" {
|
||||
val input = sequenceOf(1, 2, 3, 4).peekable()
|
||||
input.peek() shouldBe 1
|
||||
input.map { it * it }.toList() shouldBe listOf(1, 4, 9, 16)
|
||||
}
|
||||
})
|
Loading…
Reference in New Issue
Block a user