kotlin.collections.KMongoIterable.kt Maven / Gradle / Ivy
/*
* Copyright (C) 2016/2020 Litote
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package kotlin.collections
import com.mongodb.Function
import com.mongodb.ServerAddress
import com.mongodb.ServerCursor
import com.mongodb.client.MongoCursor
import com.mongodb.client.MongoIterable
import java.util.function.Consumer
import kotlin.internal.HidesMembers
import kotlin.internal.InlineOnly
import kotlin.internal.NoInfer
import kotlin.internal.OnlyInputTypes
//utility class & methods ->
/**
* Utility class - this is not part of the KMongo public API.
*/
private class MongoCursorIterable(private val cursor: MongoCursor) : MongoCursor by cursor, Iterable {
override fun iterator(): Iterator = cursor
}
/**
* Utility method - this is not part of the KMongo public API.
*/
private fun MongoIterable.kCursor(): MongoCursorIterable = MongoCursorIterable(iterator())
/**
* Utility method - this is not part of the KMongo public API.
*/
fun MongoIterable.useCursor(block: (Iterable) -> R): R {
return kCursor().use(block)
}
//specific overrides
/**
* Overrides [Iterable.forEach] to ensure [MongoIterable.forEach] is called.
*
* @param
*/
@HidesMembers
inline fun MongoIterable.forEach(crossinline action: (T) -> Unit): Unit =
forEach(Consumer { action.invoke(it) })
/**
* Returns the first element, or `null` if the collection is empty.
*/
fun MongoIterable.firstOrNull(): T? {
return first()
}
/**
* Iterator transforming original `iterator` into iterator of [IndexedValue], counting index from zero.
*/
private class MongoIndexingIterator(val iterator: MongoCursor) : MongoCursor> {
private var index = 0
override fun hasNext(): Boolean = iterator.hasNext()
override fun next(): IndexedValue = IndexedValue(index++, iterator.next())
override fun tryNext(): IndexedValue? = iterator.tryNext()?.let { IndexedValue(index++, it) }
override fun remove() = iterator.remove()
override fun close() = iterator.close()
override fun getServerCursor(): ServerCursor? = iterator.serverCursor
override fun getServerAddress(): ServerAddress = iterator.serverAddress
}
/**
* A wrapper over another [Iterable] (or any other object that can produce an [Iterator]) that returns
* an indexing iterator.
*/
private class MongoIndexingIterable(
private val iterable: MongoIterable
) : MongoIterable> {
override fun batchSize(batchSize: Int): MongoIterable> =
MongoIndexingIterable(iterable.batchSize(batchSize))
override fun map(mapper: Function, U>): MongoIterable {
var index = 0
return iterable.map { mapper.apply(IndexedValue(index++, it)) }
}
override fun forEach(action: Consumer>) {
var index = 0
iterable.forEach {
action.accept(IndexedValue(index++, it))
}
}
override fun first(): IndexedValue = IndexedValue(0, iterable.first())
override fun >> into(target: A): A {
val l = mutableListOf()
return target.apply { addAll(iterable.into(l).mapIndexed { i, v -> IndexedValue(i, v) }) }
}
override fun cursor(): MongoCursor> = iterator()
override fun iterator(): MongoCursor> = MongoIndexingIterator(iterable.iterator())
}
/**
* Returns a lazy [Iterable] of [IndexedValue] for each element of the original collection.
*/
fun MongoIterable.withIndex(): MongoIterable> {
return MongoIndexingIterable(this)
}
/**
* Returns an [Iterator] wrapping each value produced by this [Iterator] with the [IndexedValue],
* containing value and it's index.
* @sample samples.collections.Iterators.withIndexIterator
*/
fun MongoCursor.withIndex(): MongoCursor> =
MongoIndexingIterator(this)
/**
* Returns an original collection containing all the non-`null` elements, throwing an [IllegalArgumentException] if there are any `null` elements.
*/
fun MongoIterable.requireNoNulls(): Iterable =
toList().requireNoNulls()
/**
* Creates a [Sequence] instance that wraps the original collection returning its elements when being iterated.
*
* @sample samples.collections.Sequences.Building.sequenceFromCollection
*/
fun MongoIterable.asSequence(): Sequence {
//lazy sequence
return object : Sequence {
override fun iterator(): Iterator = [email protected]().asSequence().iterator()
}
}
//common overrides ->
/**
* Returns `true` if [element] is found in the collection.
*/
operator fun <@OnlyInputTypes T> MongoIterable.contains(element: T): Boolean {
return useCursor { it.contains(element) }
}
/**
* Returns an element at the given [index] or throws an [IndexOutOfBoundsException] if the [index] is out of bounds of this collection.
*/
fun MongoIterable.elementAt(index: Int): T {
return useCursor { it.elementAt(index) }
}
/**
* Returns an element at the given [index] or the result of calling the [defaultValue] function if the [index] is out of bounds of this collection.
*/
fun MongoIterable.elementAtOrElse(index: Int, defaultValue: (Int) -> T): T {
return useCursor { it.elementAtOrElse(index, defaultValue) }
}
/**
* Returns an element at the given [index] or `null` if the [index] is out of bounds of this collection.
*/
fun MongoIterable.elementAtOrNull(index: Int): T? {
return useCursor { it.elementAtOrNull(index) }
}
/**
* Returns the first element matching the given [predicate], or `null` if no such element was found.
*/
@InlineOnly
inline fun MongoIterable.find(crossinline predicate: (T) -> Boolean): T? {
return useCursor { it.find(predicate) }
}
/**
* Returns the last element matching the given [predicate], or `null` if no such element was found.
*/
@InlineOnly
inline fun MongoIterable.findLast(crossinline predicate: (T) -> Boolean): T? {
return useCursor { it.findLast(predicate) }
}
/**
* Returns the first element matching the given [predicate].
* @throws [NoSuchElementException] if no such element is found.
*/
inline fun MongoIterable.first(crossinline predicate: (T) -> Boolean): T {
return useCursor { it.first(predicate) }
}
/**
* Returns the first element matching the given [predicate], or `null` if element was not found.
*/
inline fun MongoIterable.firstOrNull(crossinline predicate: (T) -> Boolean): T? {
return useCursor { it.firstOrNull(predicate) }
}
/**
* Returns first index of [element], or -1 if the collection does not contain element.
*/
fun <@OnlyInputTypes T> MongoIterable.indexOf(element: T): Int {
return useCursor { it.indexOf(element) }
}
/**
* Returns index of the first element matching the given [predicate], or -1 if the collection does not contain such element.
*/
inline fun MongoIterable.indexOfFirst(crossinline predicate: (T) -> Boolean): Int {
return useCursor { it.indexOfFirst(predicate) }
}
/**
* Returns index of the last element matching the given [predicate], or -1 if the collection does not contain such element.
*/
inline fun MongoIterable.indexOfLast(crossinline predicate: (T) -> Boolean): Int {
return useCursor { it.indexOfLast(predicate) }
}
/**
* Returns the last element.
* @throws [NoSuchElementException] if the collection is empty.
*/
fun MongoIterable.last(): T {
return useCursor { it.last() }
}
/**
* Returns the last element matching the given [predicate].
* @throws [NoSuchElementException] if no such element is found.
*/
inline fun MongoIterable.last(crossinline predicate: (T) -> Boolean): T {
return useCursor { it.last(predicate) }
}
/**
* Returns last index of [element], or -1 if the collection does not contain element.
*/
fun <@OnlyInputTypes T> MongoIterable.lastIndexOf(element: T): Int {
return useCursor { it.lastIndexOf(element) }
}
/**
* Returns the last element, or `null` if the collection is empty.
*/
fun MongoIterable.lastOrNull(): T? {
return useCursor { it.lastOrNull() }
}
/**
* Returns the last element matching the given [predicate], or `null` if no such element was found.
*/
inline fun MongoIterable.lastOrNull(crossinline predicate: (T) -> Boolean): T? {
return useCursor { it.lastOrNull(predicate) }
}
/**
* Returns the single element, or throws an exception if the collection is empty or has more than one element.
*/
fun MongoIterable.single(): T {
return useCursor { it.single() }
}
/**
* Returns the single element matching the given [predicate], or throws exception if there is no or more than one matching element.
*/
inline fun MongoIterable.single(crossinline predicate: (T) -> Boolean): T {
return useCursor { it.single(predicate) }
}
/**
* Returns single element, or `null` if the collection is empty or has more than one element.
*/
fun MongoIterable.singleOrNull(): T? {
return useCursor { it.singleOrNull() }
}
/**
* Returns the single element matching the given [predicate], or `null` if element was not found or more than one element was found.
*/
inline fun MongoIterable.singleOrNull(crossinline predicate: (T) -> Boolean): T? {
return useCursor { it.singleOrNull(predicate) }
}
/**
* Returns a list containing all elements except first [n] elements.
*
* @sample samples.collections.Collections.Transformations.drop
*/
fun MongoIterable.drop(n: Int): List {
return useCursor { it.drop(n) }
}
/**
* Returns a list containing all elements except first elements that satisfy the given [predicate].
*
* @sample samples.collections.Collections.Transformations.drop
*/
inline fun MongoIterable.dropWhile(crossinline predicate: (T) -> Boolean): List {
return useCursor { it.dropWhile(predicate) }
}
/**
* Returns a list containing only elements matching the given [predicate].
*/
inline fun MongoIterable.filter(crossinline predicate: (T) -> Boolean): List {
return useCursor { it.filter(predicate) }
}
/**
* Returns a list containing only elements matching the given [predicate].
* @param [predicate] function that takes the index of an element and the element itself
* and returns the result of predicate evaluation on the element.
*/
inline fun MongoIterable.filterIndexed(crossinline predicate: (index: Int, T) -> Boolean): List {
return useCursor { it.filterIndexed(predicate) }
}
/**
* Appends all elements matching the given [predicate] to the given [destination].
* @param [predicate] function that takes the index of an element and the element itself
* and returns the result of predicate evaluation on the element.
*/
inline fun > MongoIterable.filterIndexedTo(
destination: C,
crossinline predicate: (index: Int, T) -> Boolean
): C {
return useCursor { it.filterIndexedTo(destination, predicate) }
}
/**
* Returns a list containing all elements that are instances of specified type parameter R.
*/
inline fun MongoIterable<*>.filterIsInstance(): List<@NoInfer R> {
return useCursor { it.filterIsInstance() }
}
/**
* Appends all elements that are instances of specified type parameter R to the given [destination].
*/
inline fun > MongoIterable<*>.filterIsInstanceTo(destination: C): C {
return useCursor { it.filterIsInstanceTo(destination) }
}
/**
* Returns a list containing all elements not matching the given [predicate].
*/
inline fun MongoIterable.filterNot(crossinline predicate: (T) -> Boolean): List {
return useCursor { it.filterNot(predicate) }
}
/**
* Returns a list containing all elements that are not `null`.
*/
fun MongoIterable.filterNotNull(): List {
return useCursor { it.filterNotNull() }
}
/**
* Appends all elements that are not `null` to the given [destination].
*/
fun , T : Any> MongoIterable.filterNotNullTo(destination: C): C {
return useCursor { it.filterNotNullTo(destination) }
}
/**
* Appends all elements not matching the given [predicate] to the given [destination].
*/
inline fun > MongoIterable.filterNotTo(
destination: C,
crossinline predicate: (T) -> Boolean
): C {
return useCursor { it.filterNotTo(destination, predicate) }
}
/**
* Appends all elements matching the given [predicate] to the given [destination].
*/
inline fun > MongoIterable.filterTo(
destination: C,
crossinline predicate: (T) -> Boolean
): C {
return useCursor { it.filterTo(destination, predicate) }
}
/**
* Returns a list containing first [n] elements.
*
* @sample samples.collections.Collections.Transformations.take
*/
fun MongoIterable.take(n: Int): List {
return useCursor { it.take(n) }
}
/**
* Returns a list containing first elements satisfying the given [predicate].
*
* @sample samples.collections.Collections.Transformations.take
*/
inline fun MongoIterable.takeWhile(crossinline predicate: (T) -> Boolean): List {
return useCursor { it.takeWhile(predicate) }
}
/**
* Returns a list with elements in reversed order.
*/
fun MongoIterable.reversed(): List {
return useCursor { it.reversed() }
}
/**
* Returns a list of all elements sorted according to their natural sort order.
*/
fun > MongoIterable.sorted(): List {
return useCursor { it.sorted() }
}
/**
* Returns a list of all elements sorted according to natural sort order of the value returned by specified [selector] function.
*/
inline fun > MongoIterable.sortedBy(crossinline selector: (T) -> R?): List {
return useCursor { it.sortedBy(selector) }
}
/**
* Returns a list of all elements sorted descending according to natural sort order of the value returned by specified [selector] function.
*/
inline fun > MongoIterable.sortedByDescending(crossinline selector: (T) -> R?): List {
return useCursor { it.sortedByDescending(selector) }
}
/**
* Returns a list of all elements sorted descending according to their natural sort order.
*/
fun > MongoIterable.sortedDescending(): List {
return useCursor { it.sortedDescending() }
}
/**
* Returns a list of all elements sorted according to the specified [comparator].
*/
fun MongoIterable.sortedWith(comparator: Comparator): List {
return useCursor { it.sortedWith(comparator) }
}
/**
* Returns a [Map] containing key-value pairs provided by [transform] function
* applied to elements of the given collection.
*
* If any of two pairs would have the same key the last one gets added to the map.
*
* The returned map preserves the entry iteration order of the original collection.
*/
inline fun MongoIterable.associate(crossinline transform: (T) -> Pair): Map {
return useCursor { it.associate(transform) }
}
/**
* Returns a [Map] containing the elements from the given collection indexed by the key
* returned from [keySelector] function applied to each element.
*
* If any two elements would have the same key returned by [keySelector] the last one gets added to the map.
*
* The returned map preserves the entry iteration order of the original collection.
*/
inline fun MongoIterable.associateBy(crossinline keySelector: (T) -> K): Map {
return useCursor { it.associateBy(keySelector) }
}
/**
* Returns a [Map] containing the values provided by [valueTransform] and indexed by [keySelector] functions applied to elements of the given collection.
*
* If any two elements would have the same key returned by [keySelector] the last one gets added to the map.
*
* The returned map preserves the entry iteration order of the original collection.
*/
inline fun MongoIterable.associateBy(
crossinline keySelector: (T) -> K,
crossinline valueTransform: (T) -> V
): Map {
return useCursor { it.associateBy(keySelector, valueTransform) }
}
/**
* Populates and returns the [destination] mutable map with key-value pairs,
* where key is provided by the [keySelector] function applied to each element of the given collection
* and value is the element itself.
*
* If any two elements would have the same key returned by [keySelector] the last one gets added to the map.
*/
inline fun > MongoIterable.associateByTo(
destination: M,
crossinline keySelector: (T) -> K
): M {
return useCursor { it.associateByTo(destination, keySelector) }
}
/**
* Populates and returns the [destination] mutable map with key-value pairs,
* where key is provided by the [keySelector] function and
* and value is provided by the [valueTransform] function applied to elements of the given collection.
*
* If any two elements would have the same key returned by [keySelector] the last one gets added to the map.
*/
inline fun > MongoIterable.associateByTo(
destination: M,
crossinline keySelector: (T) -> K,
crossinline valueTransform: (T) -> V
): M {
return useCursor { it.associateByTo(destination, keySelector, valueTransform) }
}
/**
* Populates and returns the [destination] mutable map with key-value pairs
* provided by [transform] function applied to each element of the given collection.
*
* If any of two pairs would have the same key the last one gets added to the map.
*/
inline fun > MongoIterable.associateTo(
destination: M,
crossinline transform: (T) -> Pair
): M {
return useCursor { it.associateTo(destination, transform) }
}
/**
* Appends all elements to the given [destination] collection.
*/
fun > MongoIterable.toCollection(destination: C): C {
return useCursor { it.toCollection(destination) }
}
/**
* Returns a [HashSet] of all elements.
*/
fun MongoIterable.toHashSet(): HashSet {
return useCursor { it.toHashSet() }
}
/**
* Returns a [List] containing all elements.
*/
fun MongoIterable.toList(): List {
return useCursor { it.toList() }
}
/**
* Returns a [MutableList] filled with all elements of this collection.
*/
fun MongoIterable.toMutableList(): MutableList {
return useCursor { it.toMutableList() }
}
/**
* Returns a [Set] of all elements.
*
* The returned set preserves the element iteration order of the original collection.
*/
fun MongoIterable.toSet(): Set {
return useCursor { it.toSet() }
}
/**
* Returns a single list of all elements yielded from results of [transform] function being invoked on each element of original collection.
*/
inline fun MongoIterable.flatMap(crossinline transform: (T) -> MongoIterable): List {
return useCursor { it.flatMap(transform) }
}
/**
* Appends all elements yielded from results of [transform] function being invoked on each element of original collection, to the given [destination].
*/
inline fun > MongoIterable.flatMapTo(
destination: C,
crossinline transform: (T) -> MongoIterable
): C {
return useCursor { it.flatMapTo(destination, transform) }
}
/**
* Groups elements of the original collection by the key returned by the given [keySelector] function
* applied to each element and returns a map where each group key is associated with a list of corresponding elements.
*
* The returned map preserves the entry iteration order of the keys produced from the original collection.
*
* @sample samples.collections.Collections.Transformations.groupBy
*/
inline fun MongoIterable.groupBy(crossinline keySelector: (T) -> K): Map> {
return useCursor { it.groupBy(keySelector) }
}
/**
* Groups values returned by the [valueTransform] function applied to each element of the original collection
* by the key returned by the given [keySelector] function applied to the element
* and returns a map where each group key is associated with a list of corresponding values.
*
* The returned map preserves the entry iteration order of the keys produced from the original collection.
*
* @sample samples.collections.Collections.Transformations.groupByKeysAndValues
*/
inline fun MongoIterable.groupBy(
crossinline keySelector: (T) -> K,
crossinline valueTransform: (T) -> V
): Map> {
return useCursor { it.groupBy(keySelector, valueTransform) }
}
/**
* Groups elements of the original collection by the key returned by the given [keySelector] function
* applied to each element and puts to the [destination] map each group key associated with a list of corresponding elements.
*
* @return The [destination] map.
*
* @sample samples.collections.Collections.Transformations.groupBy
*/
inline fun >> MongoIterable.groupByTo(
destination: M,
crossinline keySelector: (T) -> K
): M {
return useCursor { it.groupByTo(destination, keySelector) }
}
/**
* Groups values returned by the [valueTransform] function applied to each element of the original collection
* by the key returned by the given [keySelector] function applied to the element
* and puts to the [destination] map each group key associated with a list of corresponding values.
*
* @return The [destination] map.
*
* @sample samples.collections.Collections.Transformations.groupByKeysAndValues
*/
inline fun >> MongoIterable.groupByTo(
destination: M,
crossinline keySelector: (T) -> K,
crossinline valueTransform: (T) -> V
): M {
return useCursor { it.groupByTo(destination, keySelector, valueTransform) }
}
/**
* Creates a [Grouping] source from a collection to be used later with one of group-and-fold operations
* using the specified [keySelector] function to extract a key from each element.
*
* @sample samples.collections.Collections.Transformations.groupingByEachCount
*/
@SinceKotlin("1.1")
inline fun MongoIterable.groupingBy(crossinline keySelector: (T) -> K): Grouping {
return useCursor { it.groupingBy(keySelector) }
}
/**
* Returns a list containing the results of applying the given [transform] function
* to each element in the original collection.
*/
inline fun MongoIterable.map(crossinline transform: (T) -> R): List {
return useCursor { it.map(transform) }
}
/**
* Returns a list containing the results of applying the given [transform] function
* to each element and its index in the original collection.
* @param [transform] function that takes the index of an element and the element itself
* and returns the result of the transform applied to the element.
*/
inline fun MongoIterable.mapIndexed(crossinline transform: (index: Int, T) -> R): List {
return useCursor { it.mapIndexed(transform) }
}
/**
* Returns a list containing only the non-null results of applying the given [transform] function
* to each element and its index in the original collection.
* @param [transform] function that takes the index of an element and the element itself
* and returns the result of the transform applied to the element.
*/
inline fun MongoIterable.mapIndexedNotNull(crossinline transform: (index: Int, T) -> R?): List {
return useCursor { it.mapIndexedNotNull(transform) }
}
/**
* Applies the given [transform] function to each element and its index in the original collection
* and appends only the non-null results to the given [destination].
* @param [transform] function that takes the index of an element and the element itself
* and returns the result of the transform applied to the element.
*/
inline fun > MongoIterable.mapIndexedNotNullTo(
destination: C,
crossinline transform: (index: Int, T) -> R?
): C {
return useCursor { it.mapIndexedNotNullTo(destination, transform) }
}
/**
* Applies the given [transform] function to each element and its index in the original collection
* and appends the results to the given [destination].
* @param [transform] function that takes the index of an element and the element itself
* and returns the result of the transform applied to the element.
*/
inline fun > MongoIterable.mapIndexedTo(
destination: C,
crossinline transform: (index: Int, T) -> R
): C {
return useCursor { it.mapIndexedTo(destination, transform) }
}
/**
* Returns a list containing only the non-null results of applying the given [transform] function
* to each element in the original collection.
*/
inline fun MongoIterable.mapNotNull(crossinline transform: (T) -> R?): List {
return useCursor { it.mapNotNull(transform) }
}
/**
* Applies the given [transform] function to each element in the original collection
* and appends only the non-null results to the given [destination].
*/
inline fun > MongoIterable.mapNotNullTo(
destination: C,
crossinline transform: (T) -> R?
): C {
return useCursor { it.mapNotNullTo(destination, transform) }
}
/**
* Applies the given [transform] function to each element of the original collection
* and appends the results to the given [destination].
*/
inline fun > MongoIterable.mapTo(
destination: C,
crossinline transform: (T) -> R
): C {
return useCursor { it.mapTo(destination, transform) }
}
/**
* Returns a list containing only distinct elements from the given collection.
*
* The elements in the resulting list are in the same order as they were in the source collection.
*/
fun MongoIterable.distinct(): List {
return useCursor { it.distinct() }
}
/**
* Returns a list containing only elements from the given collection
* having distinct keys returned by the given [selector] function.
*
* The elements in the resulting list are in the same order as they were in the source collection.
*/
inline fun MongoIterable.distinctBy(crossinline selector: (T) -> K): List {
return useCursor { it.distinctBy(selector) }
}
/**
* Returns a set containing all elements that are contained by both this set and the specified collection.
*
* The returned set preserves the element iteration order of the original collection.
*/
infix fun MongoIterable.intersect(other: Iterable): Set {
return useCursor { it.intersect(other) }
}
/**
* Returns a set containing all elements that are contained by this collection and not contained by the specified collection.
*
* The returned set preserves the element iteration order of the original collection.
*/
infix fun MongoIterable.subtract(other: Iterable): Set {
return useCursor { it.subtract(other) }
}
/**
* Returns a mutable set containing all distinct elements from the given collection.
*
* The returned set preserves the element iteration order of the original collection.
*/
fun MongoIterable.toMutableSet(): MutableSet {
return useCursor { it.toMutableSet() }
}
/**
* Returns a set containing all distinct elements from both collections.
*
* The returned set preserves the element iteration order of the original collection.
* Those elements of the [other] collection that are unique are iterated in the end
* in the order of the [other] collection.
*/
infix fun MongoIterable.union(other: Iterable): Set {
return useCursor { it.union(other) }
}
/**
* Returns `true` if all elements match the given [predicate].
*
* @sample samples.collections.Collections.Aggregates.all
*/
inline fun MongoIterable.all(crossinline predicate: (T) -> Boolean): Boolean {
return useCursor { it.all(predicate) }
}
/**
* Returns `true` if collection has at least one element.
*
* @sample samples.collections.Collections.Aggregates.any
*/
fun MongoIterable.any(): Boolean {
return useCursor { it.any() }
}
/**
* Returns `true` if at least one element matches the given [predicate].
*
* @sample samples.collections.Collections.Aggregates.anyWithPredicate
*/
inline fun MongoIterable.any(crossinline predicate: (T) -> Boolean): Boolean {
return useCursor { it.any(predicate) }
}
/**
* Returns the number of elements in this collection.
*/
fun MongoIterable.count(): Int {
return useCursor { it.count() }
}
/**
* Returns the number of elements matching the given [predicate].
*/
inline fun MongoIterable.count(crossinline predicate: (T) -> Boolean): Int {
return useCursor { it.count(predicate) }
}
/**
* Accumulates value starting with [initial] value and applying [operation] from left to right to current accumulator value and each element.
*/
inline fun MongoIterable.fold(initial: R, crossinline operation: (acc: R, T) -> R): R {
return useCursor { it.fold(initial, operation) }
}
/**
* Accumulates value starting with [initial] value and applying [operation] from left to right
* to current accumulator value and each element with its index in the original collection.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself, and calculates the next accumulator value.
*/
inline fun MongoIterable.foldIndexed(initial: R, crossinline operation: (index: Int, acc: R, T) -> R): R {
return useCursor { it.foldIndexed(initial, operation) }
}
/**
* Performs the given [action] on each element, providing sequential index with the element.
* @param [action] function that takes the index of an element and the element itself
* and performs the desired action on the element.
*/
inline fun MongoIterable.forEachIndexed(crossinline action: (index: Int, T) -> Unit): Unit {
return useCursor { it.forEachIndexed(action) }
}
/**
* Returns the largest element or `null` if there are no elements.
*
* If any of elements is `NaN` returns `NaN`.
*/
@SinceKotlin("1.1")
fun MongoIterable.max(): Double? {
return useCursor { it.max() }
}
/**
* Returns the largest element or `null` if there are no elements.
*
* If any of elements is `NaN` returns `NaN`.
*/
@SinceKotlin("1.1")
fun MongoIterable.max(): Float? {
return useCursor { it.max() }
}
/**
* Returns the largest element or `null` if there are no elements.
*/
fun > MongoIterable.max(): T? {
return useCursor { it.max() }
}
/**
* Returns the first element yielding the largest value of the given function or `null` if there are no elements.
*/
inline fun > MongoIterable