All Downloads are FREE. Search and download functionalities are using the official Maven repository.

kotlin.collections.Sequence.kt Maven / Gradle / Ivy

package kotlin

import java.util.NoSuchElementException

deprecated("Use Sequence instead.")
public trait Stream {
    /**
     * Returns an iterator that returns the values from the sequence.
     */
    public fun iterator(): Iterator
}

/**
 * A sequence that returns values through its iterator. The values are evaluated lazily, and the sequence
 * is potentially infinite.
 *
 * @param T the type of elements in the sequence.
 */
public trait Sequence : Stream

public fun Stream.toSequence(): Sequence = object : Sequence {
    override fun iterator(): Iterator = [email protected]()
}

deprecated("Use sequenceOf() instead")
public fun  streamOf(vararg elements: T): Stream = elements.stream()

deprecated("Use sequenceOf() instead")
public fun  streamOf(progression: Progression): Stream = object : Stream {
    override fun iterator(): Iterator = progression.iterator()
}

/**
 * Creates a sequence that returns the specified values.
 */
public fun  sequenceOf(vararg elements: T): Sequence = elements.sequence()

/**
 * Creates a sequence that returns all values in the specified [progression].
 */
public fun  sequenceOf(progression: Progression): Sequence = object : Sequence {
    override fun iterator(): Iterator = progression.iterator()
}

deprecated("Use FilteringSequence instead")
public class FilteringStream(stream: Stream, sendWhen: Boolean = true, predicate: (T) -> Boolean)
: Stream by FilteringSequence(stream.toSequence(), sendWhen, predicate)

/**
 * A sequence that returns the values from the underlying [sequence] that either match or do not match
 * the specified [predicate].
 *
 * @param sendWhen If `true`, values for which the predicate returns `true` are returned. Otherwise,
* values for which the predicate returns `false` are returned
 */
public class FilteringSequence(private val sequence: Sequence,
                                  private val sendWhen: Boolean = true,
                                  private val predicate: (T) -> Boolean
                                 ) : Sequence {

    override fun iterator(): Iterator = object : Iterator {
        val iterator = sequence.iterator();
        var nextState: Int = -1 // -1 for unknown, 0 for done, 1 for continue
        var nextItem: T? = null

        private fun calcNext() {
            while (iterator.hasNext()) {
                val item = iterator.next()
                if (predicate(item) == sendWhen) {
                    nextItem = item
                    nextState = 1
                    return
                }
            }
            nextState = 0
        }

        override fun next(): T {
            if (nextState == -1)
                calcNext()
            if (nextState == 0)
                throw NoSuchElementException()
            val result = nextItem
            nextItem = null
            nextState = -1
            return result as T
        }

        override fun hasNext(): Boolean {
            if (nextState == -1)
                calcNext()
            return nextState == 1
        }
    }
}

deprecated("Use TransformingSequence instead")
public class TransformingStream(stream: Stream, transformer: (T) -> R)
: Stream by TransformingSequence(stream.toSequence(), transformer)

/**
 * A sequence which returns the results of applying the given [transformer] function to the values
 * in the underlying [sequence].
 */
public class TransformingSequence(private val sequence: Sequence, private val transformer: (T) -> R) : Sequence {
    override fun iterator(): Iterator = object : Iterator {
        val iterator = sequence.iterator()
        override fun next(): R {
            return transformer(iterator.next())
        }

        override fun hasNext(): Boolean {
            return iterator.hasNext()
        }
    }
}

deprecated("Use TransformingIndexedSequence instead")
public class TransformingIndexedStream(stream: Stream, transformer: (Int, T) -> R)
: Stream by TransformingIndexedSequence(stream.toSequence(), transformer)

/**
 * A sequence which returns the results of applying the given [transformer] function to the values
 * in the underlying [sequence], where the transformer function takes the index of the value in the underlying
 * sequence along with the value itself.
 */
public class TransformingIndexedSequence(private val sequence: Sequence, private val transformer: (Int, T) -> R) : Sequence {
    override fun iterator(): Iterator = object : Iterator {
        val iterator = sequence.iterator()
        var index = 0
        override fun next(): R {
            return transformer(index++, iterator.next())
        }

        override fun hasNext(): Boolean {
            return iterator.hasNext()
        }
    }
}

deprecated("Use IndexingSequence instead")
public class IndexingStream(stream: Stream)
: Stream> by IndexingSequence(stream.toSequence())

/**
 * A sequence which combines values from the underlying [sequence] with their indices and returns them as
 * [IndexedValue] objects.
 */
public class IndexingSequence(private val sequence: Sequence) : Sequence> {
    override fun iterator(): Iterator> = object : Iterator> {
        val iterator = sequence.iterator()
        var index = 0
        override fun next(): IndexedValue {
            return IndexedValue(index++, iterator.next())
        }

        override fun hasNext(): Boolean {
            return iterator.hasNext()
        }
    }
}

deprecated("Use MergingSequence instead")
public class MergingStream(stream1: Stream, stream2: Stream, transform: (T1, T2) -> V)
: Stream by MergingSequence(stream1.toSequence(), stream2.toSequence(), transform)

/**
 * A sequence which takes the values from two parallel underlying sequences, passes them to the given
 * [transform] function and returns the values returned by that function. The sequence stops returning
 * values as soon as one of the underlying sequences stops returning values.
 */
public class MergingSequence(private val sequence1: Sequence,
                                        private val sequence2: Sequence,
                                        private val transform: (T1, T2) -> V
                                       ) : Sequence {
    override fun iterator(): Iterator = object : Iterator {
        val iterator1 = sequence1.iterator()
        val iterator2 = sequence2.iterator()
        override fun next(): V {
            return transform(iterator1.next(), iterator2.next())
        }

        override fun hasNext(): Boolean {
            return iterator1.hasNext() && iterator2.hasNext()
        }
    }
}

deprecated("Use FlatteningSequence instead")
public class FlatteningStream(stream: Stream, transformer: (T) -> Stream)
: Stream by FlatteningSequence(stream.toSequence(), { transformer(it).toSequence() })

public class FlatteningSequence(private val sequence: Sequence,
                                      private val transformer: (T) -> Sequence
                                     ) : Sequence {
    override fun iterator(): Iterator = object : Iterator {
        val iterator = sequence.iterator()
        var itemIterator: Iterator? = null

        override fun next(): R {
            if (!ensureItemIterator())
                throw NoSuchElementException()
            return itemIterator!!.next()
        }

        override fun hasNext(): Boolean {
            return ensureItemIterator()
        }

        private fun ensureItemIterator(): Boolean {
            if (itemIterator?.hasNext() == false)
                itemIterator = null

            while (itemIterator == null) {
                if (!iterator.hasNext()) {
                    return false
                } else {
                    val element = iterator.next()
                    val nextItemIterator = transformer(element).iterator()
                    if (nextItemIterator.hasNext()) {
                        itemIterator = nextItemIterator
                        return true
                    }
                }
            }
            return true
        }
    }
}

deprecated("Use MultiSequence instead")
public class Multistream(stream: Stream>)
: Stream by FlatteningSequence(stream.toSequence(), { it.toSequence() })

public class MultiSequence(private val sequence: Sequence>) : Sequence {
    override fun iterator(): Iterator = object : Iterator {
        val iterator = sequence.iterator()
        var itemIterator: Iterator? = null

        override fun next(): T {
            if (!ensureItemIterator())
                throw NoSuchElementException()
            return itemIterator!!.next()
        }

        override fun hasNext(): Boolean {
            return ensureItemIterator()
        }

        private fun ensureItemIterator(): Boolean {
            if (itemIterator?.hasNext() == false)
                itemIterator = null

            while (itemIterator == null) {
                if (!iterator.hasNext()) {
                    return false
                } else {
                    val element = iterator.next()
                    val nextItemIterator = element.iterator()
                    if (nextItemIterator.hasNext()) {
                        itemIterator = nextItemIterator
                        return true
                    }
                }
            }
            return true
        }
    }
}

deprecated("Use TakeSequence instead")
public class TakeStream(stream: Stream, count: Int)
: Stream by TakeSequence(stream.toSequence(), count)

/**
 * A sequence that returns at most [count] values from the underlying [sequence], and stops returning values
 * as soon as that count is reached.
 */
public class TakeSequence(private val sequence: Sequence,
                             private val count: Int
                            ) : Sequence {
    {
        if (count < 0)
            throw IllegalArgumentException("count should be non-negative, but is $count")
    }

    override fun iterator(): Iterator = object : Iterator {
        var left = count
        val iterator = sequence.iterator();

        override fun next(): T {
            if (left == 0)
                throw NoSuchElementException()
            left--
            return iterator.next()
        }

        override fun hasNext(): Boolean {
            return left > 0 && iterator.hasNext()
        }
    }
}

deprecated("Use TakeWhileSequence instead")
public class TakeWhileStream(stream: Stream, predicate: (T) -> Boolean) : Stream by TakeWhileSequence(stream.toSequence(), predicate)

/**
 * A sequence that returns values from the underlying [sequence] while the [predicate] function returns
 * `true`, and stops returning values once the function returns `false` for the next element.
 */
public class TakeWhileSequence(private val sequence: Sequence,
                                  private val predicate: (T) -> Boolean
                                 ) : Sequence {
    override fun iterator(): Iterator = object : Iterator {
        val iterator = sequence.iterator();
        var nextState: Int = -1 // -1 for unknown, 0 for done, 1 for continue
        var nextItem: T? = null

        private fun calcNext() {
            if (iterator.hasNext()) {
                val item = iterator.next()
                if (predicate(item)) {
                    nextState = 1
                    nextItem = item
                    return
                }
            }
            nextState = 0
        }

        override fun next(): T {
            if (nextState == -1)
                calcNext() // will change nextState
            if (nextState == 0)
                throw NoSuchElementException()
            val result = nextItem as T

            // Clean next to avoid keeping reference on yielded instance
            nextItem = null
            nextState = -1
            return result
        }

        override fun hasNext(): Boolean {
            if (nextState == -1)
                calcNext() // will change nextState
            return nextState == 1
        }
    }
}

deprecated("Use DropSequence instead")
public class DropStream(stream: Stream, count: Int)
: Stream by DropSequence(stream.toSequence(), count)

/**
 * A sequence that skips the specified number of values from the underlying [sequence] and returns
 * all values after that.
 */
public class DropSequence(private val sequence: Sequence,
                             private val count: Int
                            ) : Sequence {
    {
        if (count < 0)
            throw IllegalArgumentException("count should be non-negative, but is $count")
    }

    override fun iterator(): Iterator = object : Iterator {
        val iterator = sequence.iterator();
        var left = count

        // Shouldn't be called from constructor to avoid premature iteration
        private fun drop() {
            while (left > 0 && iterator.hasNext()) {
                iterator.next()
                left--
            }
        }

        override fun next(): T {
            drop()
            return iterator.next()
        }

        override fun hasNext(): Boolean {
            drop()
            return iterator.hasNext()
        }
    }
}

deprecated("Use DropWhileSequence instead")
public class DropWhileStream(stream: Stream, predicate: (T) -> Boolean) : Stream by DropWhileSequence(stream.toSequence(), predicate)

/**
 * A sequence that skips the values from the underlying [sequence] while the given [predicate] returns `true` and returns
 * all values after that.
 */
public class DropWhileSequence(private val sequence: Sequence,
                                  private val predicate: (T) -> Boolean
                                 ) : Sequence {

    override fun iterator(): Iterator = object : Iterator {
        val iterator = sequence.iterator();
        var dropState: Int = -1 // -1 for not dropping, 1 for nextItem, 0 for normal iteration
        var nextItem: T? = null

        private fun drop() {
            while (iterator.hasNext()) {
                val item = iterator.next()
                if (!predicate(item)) {
                    nextItem = item
                    dropState = 1
                    return
                }
            }
            dropState = 0
        }

        override fun next(): T {
            if (dropState == -1)
                drop()

            if (dropState == 1) {
                val result = nextItem as T
                nextItem = null
                dropState = 0
                return result
            }
            return iterator.next()
        }

        override fun hasNext(): Boolean {
            if (dropState == -1)
                drop()
            return dropState == 1 || iterator.hasNext()
        }
    }
}

/**
 * A sequence which repeatedly calls the specified [producer] function and returns its return values, until
 * `null` is returned from [producer].
 */
public class FunctionSequence(private val producer: () -> T?) : Sequence {
    override fun iterator(): Iterator = object : Iterator {
        var nextState: Int = -1 // -1 for unknown, 0 for done, 1 for continue
        var nextItem: T? = null

        private fun calcNext() {
            val item = producer()
            if (item == null) {
                nextState = 0
            } else {
                nextState = 1
                nextItem = item
            }
        }

        override fun next(): T {
            if (nextState == -1)
                calcNext()
            if (nextState == 0)
                throw NoSuchElementException()
            val result = nextItem as T
            // Clean next to avoid keeping reference on yielded instance
            nextItem = null
            nextState = -1
            return result
        }

        override fun hasNext(): Boolean {
            if (nextState == -1)
                calcNext()
            return nextState == 1
        }

    }
}

/**
 * Returns a sequence which invokes the function to calculate the next value on each iteration until the function returns `null`.
 */
public fun  sequence(nextFunction: () -> T?): Sequence {
    return FunctionSequence(nextFunction)
}

deprecated("Use sequence() instead")
public fun  stream(nextFunction: () -> T?): Sequence = sequence(nextFunction)

/**
 * Returns a sequence 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  sequence(initialValue: T, nextFunction: (T) -> T?): Sequence =
        sequence(nextFunction.toGenerator(initialValue))

deprecated("Use sequence() instead")
public /*inline*/ fun  stream(initialValue: T, nextFunction: (T) -> T?): Sequence = sequence(initialValue, nextFunction)




© 2015 - 2025 Weber Informatics LLC | Privacy Policy