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()
|
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.shouldBe
|
||||||
import io.kotlintest.specs.ShouldSpec
|
import io.kotlintest.specs.ShouldSpec
|
||||||
|
|
||||||
class SekwencesTest : ShouldSpec({
|
class CoalesceTest : ShouldSpec({
|
||||||
"should merge numbers" {
|
"should merge numbers" {
|
||||||
val input = sequenceOf(1, 2, 3, 4, 5, 6, 4)
|
val input = sequenceOf(1, 2, 3, 4, 5, 6, 4)
|
||||||
val output = input.coalesce { first, second ->
|
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