kotlin.Iterators.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-stdlib Show documentation
Show all versions of kotlin-stdlib Show documentation
Kotlin Standard Library for JVM
package kotlin
import kotlin.support.*
import java.util.Collections
import kotlin.test.assertTrue
/**
* Returns the given iterator itself. This allows to use an instance of iterator in a ranged for-loop
*/
public fun Iterator.iterator(): Iterator = this
/**
* Returns an iterator which invokes the function to calculate the next value on each iteration until the function returns *null*
*/
public fun iterate(nextFunction: () -> T?) : Iterator {
return FunctionIterator(nextFunction)
}
/**
* Returns an iterator which invokes the function to calculate the next value based on the previous one on each iteration
* until the function returns *null*
*/
public /*inline*/ fun iterate(initialValue: T, nextFunction: (T) -> T?): Iterator =
iterate(nextFunction.toGenerator(initialValue))
/**
* Returns an iterator whose values are pairs composed of values produced by given pair of iterators
*/
public fun Iterator.zip(iterator: Iterator): Iterator> = PairIterator(this, iterator)
/**
* Returns an iterator shifted to right by the given number of elements
*/
public fun Iterator.skip(n: Int): Iterator = SkippingIterator(this, n)
class FilterIterator(val iterator : Iterator, val predicate: (T)-> Boolean) : AbstractIterator() {
override protected fun computeNext(): Unit {
while (iterator.hasNext()) {
val next = iterator.next()
if ((predicate)(next)) {
setNext(next)
return
}
}
done()
}
}
class FilterNotNullIterator(val iterator : Iterator?) : AbstractIterator() {
override protected fun computeNext(): Unit {
if (iterator != null) {
while (iterator.hasNext()) {
val next = iterator.next()
if (next != null) {
setNext(next)
return
}
}
}
done()
}
}
class MapIterator(val iterator : Iterator, val transform: (T) -> R) : AbstractIterator() {
override protected fun computeNext() : Unit {
if (iterator.hasNext()) {
setNext((transform)(iterator.next()))
} else {
done()
}
}
}
class FlatMapIterator(val iterator : Iterator, val transform: (T) -> Iterator) : AbstractIterator() {
var transformed: Iterator = iterate { null }
override protected fun computeNext() : Unit {
while (true) {
if (transformed.hasNext()) {
setNext(transformed.next())
return
}
if (iterator.hasNext()) {
transformed = (transform)(iterator.next())
} else {
done()
return
}
}
}
}
class TakeWhileIterator(val iterator: Iterator, val predicate: (T) -> Boolean) : AbstractIterator() {
override protected fun computeNext() : Unit {
if (iterator.hasNext()) {
val item = iterator.next()
if ((predicate)(item)) {
setNext(item)
return
}
}
done()
}
}
/** An [[Iterator]] which invokes a function to calculate the next value in the iteration until the function returns *null* */
class FunctionIterator(val nextFunction: () -> T?): AbstractIterator() {
override protected fun computeNext(): Unit {
val next = (nextFunction)()
if (next == null) {
done()
} else {
setNext(next)
}
}
}
/** An [[Iterator]] which iterates over a number of iterators in sequence */
fun CompositeIterator(vararg iterators: Iterator): CompositeIterator = CompositeIterator(iterators.iterator())
class CompositeIterator(val iterators: Iterator>): AbstractIterator() {
var currentIter: Iterator? = null
override protected fun computeNext(): Unit {
while (true) {
if (currentIter == null) {
if (iterators.hasNext()) {
currentIter = iterators.next()
} else {
done()
return
}
}
val iter = currentIter
if (iter != null) {
if (iter.hasNext()) {
setNext(iter.next())
return
} else {
currentIter = null
}
}
}
}
}
/** A singleton [[Iterator]] which invokes once over a value */
class SingleIterator(val value: T): AbstractIterator() {
var first = true
override protected fun computeNext(): Unit {
if (first) {
first = false
setNext(value)
} else {
done()
}
}
}
class IndexIterator(val iterator : Iterator): Iterator> {
private var index : Int = 0
override fun next(): Pair {
return Pair(index++, iterator.next())
}
override fun hasNext(): Boolean {
return iterator.hasNext()
}
}
public class PairIterator(
val iterator1 : Iterator, val iterator2 : Iterator
): AbstractIterator>() {
protected override fun computeNext() {
if (iterator1.hasNext() && iterator2.hasNext()) {
setNext(Pair(iterator1.next(), iterator2.next()))
}
else {
done()
}
}
}
class SkippingIterator(val iterator: Iterator, val n: Int): Iterator {
private var firstTime: Boolean = true
private fun skip() {
for (i in 1..n) {
if (!iterator.hasNext()) break
iterator.next()
}
firstTime = false
}
override fun next(): T {
assertTrue(!firstTime, "hasNext() must be invoked before advancing an iterator")
return iterator.next()
}
override fun hasNext(): Boolean {
if (firstTime) {
skip()
}
return iterator.hasNext()
}
}
public fun Function1.toGenerator(initialValue: T): Function0 {
var nextValue: T? = initialValue
return {
nextValue?.let { result ->
nextValue = this@toGenerator(result)
result
}
}
}