Implement reduceIndexedOrNull and reduceRightIndexedOrNull #KT-36866

This commit is contained in:
Abduqodiri Qurbonzoda
2020-03-06 13:49:22 +03:00
parent b60633d79a
commit b1fac4e721
13 changed files with 964 additions and 0 deletions
@@ -13562,6 +13562,186 @@ public inline fun CharArray.reduceIndexed(operation: (index: Int, acc: Char, Cha
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right
* to current accumulator value and each element with its index in the original array.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
public inline fun <S, T : S> Array<out T>.reduceIndexedOrNull(operation: (index: Int, acc: S, T) -> S): S? {
if (isEmpty())
return null
var accumulator: S = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right
* to current accumulator value and each element with its index in the original array.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
public inline fun ByteArray.reduceIndexedOrNull(operation: (index: Int, acc: Byte, Byte) -> Byte): Byte? {
if (isEmpty())
return null
var accumulator = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right
* to current accumulator value and each element with its index in the original array.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
public inline fun ShortArray.reduceIndexedOrNull(operation: (index: Int, acc: Short, Short) -> Short): Short? {
if (isEmpty())
return null
var accumulator = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right
* to current accumulator value and each element with its index in the original array.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
public inline fun IntArray.reduceIndexedOrNull(operation: (index: Int, acc: Int, Int) -> Int): Int? {
if (isEmpty())
return null
var accumulator = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right
* to current accumulator value and each element with its index in the original array.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
public inline fun LongArray.reduceIndexedOrNull(operation: (index: Int, acc: Long, Long) -> Long): Long? {
if (isEmpty())
return null
var accumulator = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right
* to current accumulator value and each element with its index in the original array.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
public inline fun FloatArray.reduceIndexedOrNull(operation: (index: Int, acc: Float, Float) -> Float): Float? {
if (isEmpty())
return null
var accumulator = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right
* to current accumulator value and each element with its index in the original array.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
public inline fun DoubleArray.reduceIndexedOrNull(operation: (index: Int, acc: Double, Double) -> Double): Double? {
if (isEmpty())
return null
var accumulator = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right
* to current accumulator value and each element with its index in the original array.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
public inline fun BooleanArray.reduceIndexedOrNull(operation: (index: Int, acc: Boolean, Boolean) -> Boolean): Boolean? {
if (isEmpty())
return null
var accumulator = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right
* to current accumulator value and each element with its index in the original array.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
public inline fun CharArray.reduceIndexedOrNull(operation: (index: Int, acc: Char, Char) -> Char): Char? {
if (isEmpty())
return null
var accumulator = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element. Returns null if the array is empty.
*
@@ -14021,6 +14201,195 @@ public inline fun CharArray.reduceRightIndexed(operation: (index: Int, Char, acc
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left
* to each element with its index in the original array and current accumulator value.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, the element itself
* and current accumulator value, and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceRightOrNull
*/
@SinceKotlin("1.4")
public inline fun <S, T : S> Array<out T>.reduceRightIndexedOrNull(operation: (index: Int, T, acc: S) -> S): S? {
var index = lastIndex
if (index < 0) return null
var accumulator: S = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left
* to each element with its index in the original array and current accumulator value.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, the element itself
* and current accumulator value, and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceRightOrNull
*/
@SinceKotlin("1.4")
public inline fun ByteArray.reduceRightIndexedOrNull(operation: (index: Int, Byte, acc: Byte) -> Byte): Byte? {
var index = lastIndex
if (index < 0) return null
var accumulator = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left
* to each element with its index in the original array and current accumulator value.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, the element itself
* and current accumulator value, and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceRightOrNull
*/
@SinceKotlin("1.4")
public inline fun ShortArray.reduceRightIndexedOrNull(operation: (index: Int, Short, acc: Short) -> Short): Short? {
var index = lastIndex
if (index < 0) return null
var accumulator = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left
* to each element with its index in the original array and current accumulator value.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, the element itself
* and current accumulator value, and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceRightOrNull
*/
@SinceKotlin("1.4")
public inline fun IntArray.reduceRightIndexedOrNull(operation: (index: Int, Int, acc: Int) -> Int): Int? {
var index = lastIndex
if (index < 0) return null
var accumulator = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left
* to each element with its index in the original array and current accumulator value.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, the element itself
* and current accumulator value, and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceRightOrNull
*/
@SinceKotlin("1.4")
public inline fun LongArray.reduceRightIndexedOrNull(operation: (index: Int, Long, acc: Long) -> Long): Long? {
var index = lastIndex
if (index < 0) return null
var accumulator = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left
* to each element with its index in the original array and current accumulator value.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, the element itself
* and current accumulator value, and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceRightOrNull
*/
@SinceKotlin("1.4")
public inline fun FloatArray.reduceRightIndexedOrNull(operation: (index: Int, Float, acc: Float) -> Float): Float? {
var index = lastIndex
if (index < 0) return null
var accumulator = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left
* to each element with its index in the original array and current accumulator value.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, the element itself
* and current accumulator value, and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceRightOrNull
*/
@SinceKotlin("1.4")
public inline fun DoubleArray.reduceRightIndexedOrNull(operation: (index: Int, Double, acc: Double) -> Double): Double? {
var index = lastIndex
if (index < 0) return null
var accumulator = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left
* to each element with its index in the original array and current accumulator value.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, the element itself
* and current accumulator value, and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceRightOrNull
*/
@SinceKotlin("1.4")
public inline fun BooleanArray.reduceRightIndexedOrNull(operation: (index: Int, Boolean, acc: Boolean) -> Boolean): Boolean? {
var index = lastIndex
if (index < 0) return null
var accumulator = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left
* to each element with its index in the original array and current accumulator value.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, the element itself
* and current accumulator value, and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceRightOrNull
*/
@SinceKotlin("1.4")
public inline fun CharArray.reduceRightIndexedOrNull(operation: (index: Int, Char, acc: Char) -> Char): Char? {
var index = lastIndex
if (index < 0) return null
var accumulator = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left to each element and current accumulator value. Returns null if the array is empty.
*
@@ -1893,6 +1893,27 @@ public inline fun <S, T : S> Iterable<T>.reduceIndexed(operation: (index: Int, a
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right
* to current accumulator value and each element with its index in the original collection.
* Returns null if the collection is empty.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
public inline fun <S, T : S> Iterable<T>.reduceIndexedOrNull(operation: (index: Int, acc: S, T) -> S): S? {
val iterator = this.iterator()
if (!iterator.hasNext()) return null
var index = 1
var accumulator: S = iterator.next()
while (iterator.hasNext()) {
accumulator = operation(checkIndexOverflow(index++), accumulator, iterator.next())
}
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element. Returns null if the collection is empty.
*
@@ -1946,6 +1967,28 @@ public inline fun <S, T : S> List<T>.reduceRightIndexed(operation: (index: Int,
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left
* to each element with its index in the original list and current accumulator value.
* Returns null if the list is empty.
* @param [operation] function that takes the index of an element, the element itself
* and current accumulator value, and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceRightOrNull
*/
@SinceKotlin("1.4")
public inline fun <S, T : S> List<T>.reduceRightIndexedOrNull(operation: (index: Int, T, acc: S) -> S): S? {
val iterator = listIterator(size)
if (!iterator.hasPrevious())
return null
var accumulator: S = iterator.previous()
while (iterator.hasPrevious()) {
val index = iterator.previousIndex()
accumulator = operation(index, iterator.previous(), accumulator)
}
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left to each element and current accumulator value. Returns null if the list is empty.
*
@@ -1388,6 +1388,29 @@ public inline fun <S, T : S> Sequence<T>.reduceIndexed(operation: (index: Int, a
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right
* to current accumulator value and each element with its index in the original sequence.
* Returns null if the sequence is empty.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself and calculates the next accumulator value.
*
* The operation is _terminal_.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
public inline fun <S, T : S> Sequence<T>.reduceIndexedOrNull(operation: (index: Int, acc: S, T) -> S): S? {
val iterator = this.iterator()
if (!iterator.hasNext()) return null
var index = 1
var accumulator: S = iterator.next()
while (iterator.hasNext()) {
accumulator = operation(checkIndexOverflow(index++), accumulator, iterator.next())
}
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element. Returns null if the sequence is empty.
*
@@ -1220,6 +1220,26 @@ public inline fun CharSequence.reduceIndexed(operation: (index: Int, acc: Char,
return accumulator
}
/**
* Accumulates value starting with the first character and applying [operation] from left to right
* to current accumulator value and each character with its index in the original char sequence.
* Returns null if the char sequence is empty.
* @param [operation] function that takes the index of a character, current accumulator value
* and the character itself and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
public inline fun CharSequence.reduceIndexedOrNull(operation: (index: Int, acc: Char, Char) -> Char): Char? {
if (isEmpty())
return null
var accumulator = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
}
/**
* Accumulates value starting with the first character and applying [operation] from left to right to current accumulator value and each character. Returns null if the char sequence is empty.
*
@@ -1271,6 +1291,27 @@ public inline fun CharSequence.reduceRightIndexed(operation: (index: Int, Char,
return accumulator
}
/**
* Accumulates value starting with last character and applying [operation] from right to left
* to each character with its index in the original char sequence and current accumulator value.
* Returns null if the char sequence is empty.
* @param [operation] function that takes the index of a character, the character itself
* and current accumulator value, and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceRightOrNull
*/
@SinceKotlin("1.4")
public inline fun CharSequence.reduceRightIndexedOrNull(operation: (index: Int, Char, acc: Char) -> Char): Char? {
var index = lastIndex
if (index < 0) return null
var accumulator = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
}
/**
* Accumulates value starting with last character and applying [operation] from right to left to each character and current accumulator value. Returns null if the char sequence is empty.
*
@@ -6002,6 +6002,94 @@ public inline fun UShortArray.reduceIndexed(operation: (index: Int, acc: UShort,
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right
* to current accumulator value and each element with its index in the original array.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
@ExperimentalUnsignedTypes
@kotlin.internal.InlineOnly
public inline fun UIntArray.reduceIndexedOrNull(operation: (index: Int, acc: UInt, UInt) -> UInt): UInt? {
if (isEmpty())
return null
var accumulator = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right
* to current accumulator value and each element with its index in the original array.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
@ExperimentalUnsignedTypes
@kotlin.internal.InlineOnly
public inline fun ULongArray.reduceIndexedOrNull(operation: (index: Int, acc: ULong, ULong) -> ULong): ULong? {
if (isEmpty())
return null
var accumulator = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right
* to current accumulator value and each element with its index in the original array.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
@ExperimentalUnsignedTypes
@kotlin.internal.InlineOnly
public inline fun UByteArray.reduceIndexedOrNull(operation: (index: Int, acc: UByte, UByte) -> UByte): UByte? {
if (isEmpty())
return null
var accumulator = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right
* to current accumulator value and each element with its index in the original array.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, current accumulator value
* and the element itself and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceOrNull
*/
@SinceKotlin("1.4")
@ExperimentalUnsignedTypes
@kotlin.internal.InlineOnly
public inline fun UShortArray.reduceIndexedOrNull(operation: (index: Int, acc: UShort, UShort) -> UShort): UShort? {
if (isEmpty())
return null
var accumulator = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
}
/**
* Accumulates value starting with the first element and applying [operation] from left to right to current accumulator value and each element. Returns null if the array is empty.
*
@@ -6238,6 +6326,98 @@ public inline fun UShortArray.reduceRightIndexed(operation: (index: Int, UShort,
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left
* to each element with its index in the original array and current accumulator value.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, the element itself
* and current accumulator value, and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceRightOrNull
*/
@SinceKotlin("1.4")
@ExperimentalUnsignedTypes
@kotlin.internal.InlineOnly
public inline fun UIntArray.reduceRightIndexedOrNull(operation: (index: Int, UInt, acc: UInt) -> UInt): UInt? {
var index = lastIndex
if (index < 0) return null
var accumulator = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left
* to each element with its index in the original array and current accumulator value.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, the element itself
* and current accumulator value, and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceRightOrNull
*/
@SinceKotlin("1.4")
@ExperimentalUnsignedTypes
@kotlin.internal.InlineOnly
public inline fun ULongArray.reduceRightIndexedOrNull(operation: (index: Int, ULong, acc: ULong) -> ULong): ULong? {
var index = lastIndex
if (index < 0) return null
var accumulator = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left
* to each element with its index in the original array and current accumulator value.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, the element itself
* and current accumulator value, and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceRightOrNull
*/
@SinceKotlin("1.4")
@ExperimentalUnsignedTypes
@kotlin.internal.InlineOnly
public inline fun UByteArray.reduceRightIndexedOrNull(operation: (index: Int, UByte, acc: UByte) -> UByte): UByte? {
var index = lastIndex
if (index < 0) return null
var accumulator = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left
* to each element with its index in the original array and current accumulator value.
* Returns null if the array is empty.
* @param [operation] function that takes the index of an element, the element itself
* and current accumulator value, and calculates the next accumulator value.
*
* @sample samples.collections.Collections.Aggregates.reduceRightOrNull
*/
@SinceKotlin("1.4")
@ExperimentalUnsignedTypes
@kotlin.internal.InlineOnly
public inline fun UShortArray.reduceRightIndexedOrNull(operation: (index: Int, UShort, acc: UShort) -> UShort): UShort? {
var index = lastIndex
if (index < 0) return null
var accumulator = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
}
/**
* Accumulates value starting with last element and applying [operation] from right to left to each element and current accumulator value. Returns null if the array is empty.
*
@@ -698,6 +698,7 @@ class Collections {
fun reduceOrNull() {
val strings = listOf("a", "b", "c", "d")
assertPrints(strings.reduceOrNull { acc, string -> acc + string }, "abcd")
assertPrints(strings.reduceIndexedOrNull { index, acc, string -> acc + string + index }, "ab1c2d3")
assertPrints(emptyList<String>().reduceOrNull { _, _ -> "" }, "null")
}
@@ -706,6 +707,7 @@ class Collections {
fun reduceRightOrNull() {
val strings = listOf("a", "b", "c", "d")
assertPrints(strings.reduceRightOrNull { string, acc -> acc + string }, "dcba")
assertPrints(strings.reduceRightIndexedOrNull { index, string, acc -> acc + string + index }, "dc2b1a0")
assertPrints(emptyList<String>().reduceRightOrNull { _, _ -> "" }, "null")
}
@@ -1016,6 +1016,20 @@ class ArraysTest {
}
}
@Test fun reduceIndexedOrNull() {
expect(-1) { intArrayOf(1, 2, 3).reduceIndexedOrNull { index, a, b -> index + a - b } }
expect(-1.toLong()) { longArrayOf(1, 2, 3).reduceIndexedOrNull { index, a, b -> index + a - b } }
expect(-1F) { floatArrayOf(1F, 2F, 3F).reduceIndexedOrNull { index, a, b -> index + a - b } }
expect(-1.0) { doubleArrayOf(1.0, 2.0, 3.0).reduceIndexedOrNull { index, a, b -> index + a - b } }
expect('2') { charArrayOf('1', '3', '2').reduceIndexedOrNull { index, a, b -> if (a > b && index == 1) a else b } }
expect(true) { booleanArrayOf(true, true, false).reduceIndexedOrNull { index, a, b -> a && b || index == 2 } }
expect(false) { booleanArrayOf(true, true).reduceIndexedOrNull { index, a, b -> a && b && index != 1 } }
expect(1.toByte()) { byteArrayOf(3, 2, 1).reduceIndexedOrNull { index, a, b -> if (index != 2) (a - b).toByte() else a.toByte() } }
expect(1.toShort()) { shortArrayOf(3, 2, 1).reduceIndexedOrNull { index, a, b -> if (index != 2) (a - b).toShort() else a.toShort() } }
expect(null, { intArrayOf().reduceIndexedOrNull { index, a, b -> index + a + b } })
}
@Test fun reduceRightIndexed() {
expect(1) { intArrayOf(1, 2, 3).reduceRightIndexed { index, a, b -> index + a - b } }
expect(1.toLong()) { longArrayOf(1, 2, 3).reduceRightIndexed { index, a, b -> index + a - b } }
@@ -1032,6 +1046,20 @@ class ArraysTest {
}
}
@Test fun reduceRightIndexedOrNull() {
expect(1) { intArrayOf(1, 2, 3).reduceRightIndexedOrNull { index, a, b -> index + a - b } }
expect(1.toLong()) { longArrayOf(1, 2, 3).reduceRightIndexedOrNull { index, a, b -> index + a - b } }
expect(1F) { floatArrayOf(1F, 2F, 3F).reduceRightIndexedOrNull { index, a, b -> index + a - b } }
expect(1.0) { doubleArrayOf(1.0, 2.0, 3.0).reduceRightIndexedOrNull { index, a, b -> index + a - b } }
expect('2') { charArrayOf('1', '3', '2').reduceRightIndexedOrNull { index, a, b -> if (a > b && index == 0) a else b } }
expect(true) { booleanArrayOf(true, true, false).reduceRightIndexedOrNull { index, a, b -> a && b || index == 1 } }
expect(false) { booleanArrayOf(true, true).reduceRightIndexedOrNull { index, a, b -> a && b && index != 0 } }
expect(1.toByte()) { byteArrayOf(3, 2, 1).reduceRightIndexedOrNull { index, a, b -> if (index != 1) (a - b).toByte() else a.toByte() } }
expect(1.toShort()) { shortArrayOf(3, 2, 1).reduceRightIndexedOrNull { index, a, b -> if (index != 1) (a - b).toShort() else a.toShort() } }
expect(null, { intArrayOf().reduceRightIndexedOrNull { index, a, b -> index + a + b } })
}
@Test fun reduce() {
expect(-4) { intArrayOf(1, 2, 3).reduce { a, b -> a - b } }
expect(-4.toLong()) { longArrayOf(1, 2, 3).reduce { a, b -> a - b } }
@@ -296,6 +296,24 @@ class CollectionTest {
}
}
@Test fun reduceIndexedOrNull() {
expect("123") {
val list = listOf("1", "2", "3", "4")
list.reduceIndexedOrNull { index, a, b -> if (index == 3) a else a + b }
}
expect(5) {
listOf(2, 3).reduceIndexedOrNull { index, acc: Number, e ->
assertEquals(1, index)
assertEquals(2, acc)
assertEquals(3, e)
acc.toInt() + e
}
}
expect(null, { arrayListOf<Int>().reduceIndexedOrNull { index, a, b -> index + a + b } })
}
@Test fun reduceRightIndexed() {
expect("234") {
val list = listOf("1", "2", "3", "4")
@@ -316,6 +334,24 @@ class CollectionTest {
}
}
@Test fun reduceRightIndexedOrNull() {
expect("234") {
val list = listOf("1", "2", "3", "4")
list.reduceRightIndexedOrNull { index, a, b -> if (index == 0) b else a + b }
}
expect(1) {
listOf(2, 3).reduceRightIndexedOrNull { index, e, acc: Number ->
assertEquals(0, index)
assertEquals(3, acc)
assertEquals(2, e)
acc.toInt() - e
}
}
expect(null, { arrayListOf<Int>().reduceRightIndexedOrNull { index, a, b -> index + a + b } })
}
@Test fun reduce() {
expect("1234") {
val list = listOf("1", "2", "3", "4")
@@ -426,6 +426,10 @@ public class SequenceTest {
expect(null, { sequenceOf<Int>().reduceOrNull { acc, i -> acc + i } })
}
@Test fun reduceIndexedOrNullOnEmpty() {
expect(null, { sequenceOf<Int>().reduceIndexedOrNull { index, acc, i -> acc + i + index } })
}
@Test fun minusElement() = testMinus(expected = listOf("foo", "bar")) { it - "bar" - "zoo" }
@Test fun minusCollection() = testMinus { it - listOf("bar", "zoo") }
@Test fun minusArray() = testMinus { it - arrayOf("bar", "zoo") }
@@ -548,6 +548,16 @@ class UnsignedArraysTest {
}
}
@Test
fun reduceIndexedOrNull() {
expect(1u) { ubyteArrayOf(3, 2, 1).reduceIndexedOrNull { index, acc, e -> if (index != 2) (e - acc).toUByte() else e } }
expect(1u) { ushortArrayOf(3, 2, 1).reduceIndexedOrNull { index, acc, e -> if (index != 2) (e - acc).toUShort() else e } }
expect(UInt.MAX_VALUE) { uintArrayOf(1, 2, 3).reduceIndexedOrNull { index, acc, e -> index.toUInt() + acc - e } }
expect(ULong.MAX_VALUE) { ulongArrayOf(1, 2, 3).reduceIndexedOrNull { index, acc, e -> index.toULong() + acc - e } }
expect(null, { uintArrayOf().reduceIndexedOrNull { index, acc, e -> index.toUInt() + e + acc } })
}
@Test
fun reduceRight() {
expect(2u) { ubyteArrayOf(1, 2, 3).reduceRightOrNull { e, acc -> (e - acc).toUByte() } }
@@ -582,6 +592,16 @@ class UnsignedArraysTest {
}
}
@Test
fun reduceRightIndexedOrNull() {
expect(1u) { ubyteArrayOf(3, 2, 1).reduceRightIndexedOrNull { index, e, acc -> if (index != 1) (e - acc).toUByte() else e } }
expect(1u) { ushortArrayOf(3, 2, 1).reduceRightIndexedOrNull { index, e, acc -> if (index != 1) (e - acc).toUShort() else e } }
expect(1u) { uintArrayOf(1, 2, 3).reduceRightIndexedOrNull { index, e, acc -> index.toUInt() + e - acc } }
expect(1uL) { ulongArrayOf(1, 2, 3).reduceRightIndexedOrNull { index, e, acc -> index.toULong() + e - acc } }
expect(null, { uintArrayOf().reduceRightIndexedOrNull { index, e, acc -> index.toUInt() + e + acc } })
}
@Test
fun forEach() {
var i = 0
+32
View File
@@ -1268,6 +1268,22 @@ class StringTest {
}
}
@Test fun reduceIndexedOrNull() = withOneCharSequenceArg { arg1 ->
// get the 3rd character
assertEquals('c', arg1("bacfd").reduceIndexedOrNull { index, v, c -> if (index == 2) c else v })
expect('c') {
"ab".reduceIndexedOrNull { index, acc, e ->
assertEquals(1, index)
assertEquals('a', acc)
assertEquals('b', e)
e + (e - acc)
}
}
expect(null, { arg1("").reduceIndexedOrNull { _, _, _ -> '\n' } })
}
@Test fun reduceRightIndexed() = withOneCharSequenceArg { arg1 ->
// get the 3rd character
assertEquals('c', arg1("bacfd").reduceRightIndexed { index, c, v -> if (index == 2) c else v })
@@ -1286,6 +1302,22 @@ class StringTest {
}
}
@Test fun reduceRightIndexedOrNull() = withOneCharSequenceArg { arg1 ->
// get the 3rd character
assertEquals('c', arg1("bacfd").reduceRightIndexedOrNull { index, c, v -> if (index == 2) c else v })
expect('c') {
"ab".reduceRightIndexedOrNull { index, e, acc ->
assertEquals(0, index)
assertEquals('b', acc)
assertEquals('a', e)
acc + (acc - e)
}
}
expect(null, { arg1("").reduceRightIndexedOrNull { _, _, _ -> '\n' } })
}
@Test fun reduce() = withOneCharSequenceArg { arg1 ->
// get the smallest character(by char value)
assertEquals('a', arg1("bacfd").reduce { v, c -> if (v > c) c else v })
@@ -1491,6 +1491,15 @@ public final class kotlin/collections/ArraysKt {
public static final fun reduceIndexed ([Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Ljava/lang/Object;
public static final fun reduceIndexed ([SLkotlin/jvm/functions/Function3;)S
public static final fun reduceIndexed ([ZLkotlin/jvm/functions/Function3;)Z
public static final fun reduceIndexedOrNull ([BLkotlin/jvm/functions/Function3;)Ljava/lang/Byte;
public static final fun reduceIndexedOrNull ([CLkotlin/jvm/functions/Function3;)Ljava/lang/Character;
public static final fun reduceIndexedOrNull ([DLkotlin/jvm/functions/Function3;)Ljava/lang/Double;
public static final fun reduceIndexedOrNull ([FLkotlin/jvm/functions/Function3;)Ljava/lang/Float;
public static final fun reduceIndexedOrNull ([ILkotlin/jvm/functions/Function3;)Ljava/lang/Integer;
public static final fun reduceIndexedOrNull ([JLkotlin/jvm/functions/Function3;)Ljava/lang/Long;
public static final fun reduceIndexedOrNull ([Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Ljava/lang/Object;
public static final fun reduceIndexedOrNull ([SLkotlin/jvm/functions/Function3;)Ljava/lang/Short;
public static final fun reduceIndexedOrNull ([ZLkotlin/jvm/functions/Function3;)Ljava/lang/Boolean;
public static final fun reduceOrNull ([BLkotlin/jvm/functions/Function2;)Ljava/lang/Byte;
public static final fun reduceOrNull ([CLkotlin/jvm/functions/Function2;)Ljava/lang/Character;
public static final fun reduceOrNull ([DLkotlin/jvm/functions/Function2;)Ljava/lang/Double;
@@ -1518,6 +1527,15 @@ public final class kotlin/collections/ArraysKt {
public static final fun reduceRightIndexed ([Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Ljava/lang/Object;
public static final fun reduceRightIndexed ([SLkotlin/jvm/functions/Function3;)S
public static final fun reduceRightIndexed ([ZLkotlin/jvm/functions/Function3;)Z
public static final fun reduceRightIndexedOrNull ([BLkotlin/jvm/functions/Function3;)Ljava/lang/Byte;
public static final fun reduceRightIndexedOrNull ([CLkotlin/jvm/functions/Function3;)Ljava/lang/Character;
public static final fun reduceRightIndexedOrNull ([DLkotlin/jvm/functions/Function3;)Ljava/lang/Double;
public static final fun reduceRightIndexedOrNull ([FLkotlin/jvm/functions/Function3;)Ljava/lang/Float;
public static final fun reduceRightIndexedOrNull ([ILkotlin/jvm/functions/Function3;)Ljava/lang/Integer;
public static final fun reduceRightIndexedOrNull ([JLkotlin/jvm/functions/Function3;)Ljava/lang/Long;
public static final fun reduceRightIndexedOrNull ([Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Ljava/lang/Object;
public static final fun reduceRightIndexedOrNull ([SLkotlin/jvm/functions/Function3;)Ljava/lang/Short;
public static final fun reduceRightIndexedOrNull ([ZLkotlin/jvm/functions/Function3;)Ljava/lang/Boolean;
public static final fun reduceRightOrNull ([BLkotlin/jvm/functions/Function2;)Ljava/lang/Byte;
public static final fun reduceRightOrNull ([CLkotlin/jvm/functions/Function2;)Ljava/lang/Character;
public static final fun reduceRightOrNull ([DLkotlin/jvm/functions/Function2;)Ljava/lang/Double;
@@ -2129,9 +2147,11 @@ public final class kotlin/collections/CollectionsKt {
public static final fun randomOrNull (Ljava/util/Collection;Lkotlin/random/Random;)Ljava/lang/Object;
public static final fun reduce (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
public static final fun reduceIndexed (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function3;)Ljava/lang/Object;
public static final fun reduceIndexedOrNull (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function3;)Ljava/lang/Object;
public static final fun reduceOrNull (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
public static final fun reduceRight (Ljava/util/List;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
public static final fun reduceRightIndexed (Ljava/util/List;Lkotlin/jvm/functions/Function3;)Ljava/lang/Object;
public static final fun reduceRightIndexedOrNull (Ljava/util/List;Lkotlin/jvm/functions/Function3;)Ljava/lang/Object;
public static final fun reduceRightOrNull (Ljava/util/List;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
public static final fun removeAll (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function1;)Z
public static final fun removeAll (Ljava/util/Collection;Ljava/lang/Iterable;)Z
@@ -4660,6 +4680,7 @@ public final class kotlin/sequences/SequencesKt {
public static final fun plus (Lkotlin/sequences/Sequence;[Ljava/lang/Object;)Lkotlin/sequences/Sequence;
public static final fun reduce (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
public static final fun reduceIndexed (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function3;)Ljava/lang/Object;
public static final fun reduceIndexedOrNull (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function3;)Ljava/lang/Object;
public static final fun reduceOrNull (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object;
public static final fun requireNoNulls (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence;
public static final fun scan (Lkotlin/sequences/Sequence;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Lkotlin/sequences/Sequence;
@@ -5058,9 +5079,11 @@ public final class kotlin/text/StringsKt {
public static final fun randomOrNull (Ljava/lang/CharSequence;Lkotlin/random/Random;)Ljava/lang/Character;
public static final fun reduce (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function2;)C
public static final fun reduceIndexed (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function3;)C
public static final fun reduceIndexedOrNull (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function3;)Ljava/lang/Character;
public static final fun reduceOrNull (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function2;)Ljava/lang/Character;
public static final fun reduceRight (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function2;)C
public static final fun reduceRightIndexed (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function3;)C
public static final fun reduceRightIndexedOrNull (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function3;)Ljava/lang/Character;
public static final fun reduceRightOrNull (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function2;)Ljava/lang/Character;
public static final fun regionMatches (Ljava/lang/CharSequence;ILjava/lang/CharSequence;IIZ)Z
public static final fun regionMatches (Ljava/lang/String;ILjava/lang/String;IIZ)Z
@@ -708,6 +708,85 @@ object Aggregates : TemplateGroupBase() {
}
}
val f_reduceIndexedOrNull = fn("reduceIndexedOrNull(operation: (index: Int, acc: T, T) -> T)") {
include(ArraysOfPrimitives, ArraysOfUnsigned, CharSequences)
} builder {
since("1.4")
inline()
specialFor(ArraysOfUnsigned) { inlineOnly() }
doc {
"""
Accumulates value starting with the first ${f.element} and applying [operation] from left to right
to current accumulator value and each ${f.element} with its index in the original ${f.collection}.
Returns null if the ${f.collection} is empty.
@param [operation] function that takes the index of ${f.element.prefixWithArticle()}, current accumulator value
and the ${f.element} itself and calculates the next accumulator value.
"""
}
sample("samples.collections.Collections.Aggregates.reduceOrNull")
returns("T?")
body {
"""
if (isEmpty())
return null
var accumulator = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
"""
}
}
val f_reduceIndexedOrNullSuper = fn("reduceIndexedOrNull(operation: (index: Int, acc: S, T) -> S)") {
include(ArraysOfObjects, Iterables, Sequences)
} builder {
since("1.4")
inline()
doc {
"""
Accumulates value starting with the first ${f.element} and applying [operation] from left to right
to current accumulator value and each ${f.element} with its index in the original ${f.collection}.
Returns null if the ${f.collection} is empty.
@param [operation] function that takes the index of ${f.element.prefixWithArticle()}, current accumulator value
and the ${f.element} itself and calculates the next accumulator value.
"""
}
typeParam("S")
typeParam("T : S")
sample("samples.collections.Collections.Aggregates.reduceOrNull")
returns("S?")
body {
fun checkOverflow(value: String) = if (f == Sequences || f == Iterables) "checkIndexOverflow($value)" else value
"""
val iterator = this.iterator()
if (!iterator.hasNext()) return null
var index = 1
var accumulator: S = iterator.next()
while (iterator.hasNext()) {
accumulator = operation(${checkOverflow("index++")}, accumulator, iterator.next())
}
return accumulator
"""
}
body(ArraysOfObjects) {
"""
if (isEmpty())
return null
var accumulator: S = this[0]
for (index in 1..lastIndex) {
accumulator = operation(index, accumulator, this[index])
}
return accumulator
"""
}
}
val f_reduceRightIndexed = fn("reduceRightIndexed(operation: (index: Int, T, acc: T) -> T)") {
include(CharSequences, ArraysOfPrimitives, ArraysOfUnsigned)
} builder {
@@ -788,6 +867,90 @@ object Aggregates : TemplateGroupBase() {
}
}
val f_reduceRightIndexedOrNull = fn("reduceRightIndexedOrNull(operation: (index: Int, T, acc: T) -> T)") {
include(CharSequences, ArraysOfPrimitives, ArraysOfUnsigned)
} builder {
since("1.4")
inline()
specialFor(ArraysOfUnsigned) { inlineOnly() }
doc {
"""
Accumulates value starting with last ${f.element} and applying [operation] from right to left
to each ${f.element} with its index in the original ${f.collection} and current accumulator value.
Returns null if the ${f.collection} is empty.
@param [operation] function that takes the index of ${f.element.prefixWithArticle()}, the ${f.element} itself
and current accumulator value, and calculates the next accumulator value.
"""
}
sample("samples.collections.Collections.Aggregates.reduceRightOrNull")
returns("T?")
body {
"""
var index = lastIndex
if (index < 0) return null
var accumulator = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
"""
}
}
val f_reduceRightIndexedOrNullSuper = fn("reduceRightIndexedOrNull(operation: (index: Int, T, acc: S) -> S)") {
include(Lists, ArraysOfObjects)
} builder {
since("1.4")
inline()
doc {
"""
Accumulates value starting with last ${f.element} and applying [operation] from right to left
to each ${f.element} with its index in the original ${f.collection} and current accumulator value.
Returns null if the ${f.collection} is empty.
@param [operation] function that takes the index of ${f.element.prefixWithArticle()}, the ${f.element} itself
and current accumulator value, and calculates the next accumulator value.
"""
}
sample("samples.collections.Collections.Aggregates.reduceRightOrNull")
typeParam("S")
typeParam("T : S")
returns("S?")
body {
"""
var index = lastIndex
if (index < 0) return null
var accumulator: S = get(index--)
while (index >= 0) {
accumulator = operation(index, get(index), accumulator)
--index
}
return accumulator
"""
}
body(Lists) {
"""
val iterator = listIterator(size)
if (!iterator.hasPrevious())
return null
var accumulator: S = iterator.previous()
while (iterator.hasPrevious()) {
val index = iterator.previousIndex()
accumulator = operation(index, iterator.previous(), accumulator)
}
return accumulator
"""
}
}
val f_reduce = fn("reduce(operation: (acc: T, T) -> T)") {
include(ArraysOfPrimitives, ArraysOfUnsigned, CharSequences)
} builder {