mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-11 00:21:27 +00:00
Add foldIndexed and reduceIndexed groups of functions
- foldIndexed, foldRightIndexed, reduceIndexed and reduceRightIndexed have been added, in line with filterIndexed etc.; - Test cases added appropriately for the new functions.
This commit is contained in:
committed by
Ilya Gorbunov
parent
b3f390abe5
commit
d58efff974
@@ -8782,6 +8782,105 @@ public inline fun <R> ShortArray.fold(initial: R, operation: (R, Short) -> R): R
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 array.
|
||||
*/
|
||||
public inline fun <T, R> Array<out T>.foldIndexed(initial: R, operation: (Int, R, T) -> R): R {
|
||||
var index = 0
|
||||
var accumulator = initial
|
||||
for (element in this) accumulator = operation(index++, accumulator, element)
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 array.
|
||||
*/
|
||||
public inline fun <R> BooleanArray.foldIndexed(initial: R, operation: (Int, R, Boolean) -> R): R {
|
||||
var index = 0
|
||||
var accumulator = initial
|
||||
for (element in this) accumulator = operation(index++, accumulator, element)
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 array.
|
||||
*/
|
||||
public inline fun <R> ByteArray.foldIndexed(initial: R, operation: (Int, R, Byte) -> R): R {
|
||||
var index = 0
|
||||
var accumulator = initial
|
||||
for (element in this) accumulator = operation(index++, accumulator, element)
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 array.
|
||||
*/
|
||||
public inline fun <R> CharArray.foldIndexed(initial: R, operation: (Int, R, Char) -> R): R {
|
||||
var index = 0
|
||||
var accumulator = initial
|
||||
for (element in this) accumulator = operation(index++, accumulator, element)
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 array.
|
||||
*/
|
||||
public inline fun <R> DoubleArray.foldIndexed(initial: R, operation: (Int, R, Double) -> R): R {
|
||||
var index = 0
|
||||
var accumulator = initial
|
||||
for (element in this) accumulator = operation(index++, accumulator, element)
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 array.
|
||||
*/
|
||||
public inline fun <R> FloatArray.foldIndexed(initial: R, operation: (Int, R, Float) -> R): R {
|
||||
var index = 0
|
||||
var accumulator = initial
|
||||
for (element in this) accumulator = operation(index++, accumulator, element)
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 array.
|
||||
*/
|
||||
public inline fun <R> IntArray.foldIndexed(initial: R, operation: (Int, R, Int) -> R): R {
|
||||
var index = 0
|
||||
var accumulator = initial
|
||||
for (element in this) accumulator = operation(index++, accumulator, element)
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 array.
|
||||
*/
|
||||
public inline fun <R> LongArray.foldIndexed(initial: R, operation: (Int, R, Long) -> R): R {
|
||||
var index = 0
|
||||
var accumulator = initial
|
||||
for (element in this) accumulator = operation(index++, accumulator, element)
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 array.
|
||||
*/
|
||||
public inline fun <R> ShortArray.foldIndexed(initial: R, operation: (Int, R, Short) -> R): R {
|
||||
var index = 0
|
||||
var accumulator = initial
|
||||
for (element in this) accumulator = operation(index++, accumulator, element)
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from right to left to each element and current accumulator value.
|
||||
*/
|
||||
@@ -8890,6 +8989,132 @@ public inline fun <R> ShortArray.foldRight(initial: R, operation: (Short, R) ->
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from right to left
|
||||
* to each element with its index in the original array and current accumulator value.
|
||||
*/
|
||||
public inline fun <T, R> Array<out T>.foldRightIndexed(initial: R, operation: (Int, T, R) -> R): R {
|
||||
var index = lastIndex
|
||||
var accumulator = initial
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from right to left
|
||||
* to each element with its index in the original array and current accumulator value.
|
||||
*/
|
||||
public inline fun <R> BooleanArray.foldRightIndexed(initial: R, operation: (Int, Boolean, R) -> R): R {
|
||||
var index = lastIndex
|
||||
var accumulator = initial
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from right to left
|
||||
* to each element with its index in the original array and current accumulator value.
|
||||
*/
|
||||
public inline fun <R> ByteArray.foldRightIndexed(initial: R, operation: (Int, Byte, R) -> R): R {
|
||||
var index = lastIndex
|
||||
var accumulator = initial
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from right to left
|
||||
* to each element with its index in the original array and current accumulator value.
|
||||
*/
|
||||
public inline fun <R> CharArray.foldRightIndexed(initial: R, operation: (Int, Char, R) -> R): R {
|
||||
var index = lastIndex
|
||||
var accumulator = initial
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from right to left
|
||||
* to each element with its index in the original array and current accumulator value.
|
||||
*/
|
||||
public inline fun <R> DoubleArray.foldRightIndexed(initial: R, operation: (Int, Double, R) -> R): R {
|
||||
var index = lastIndex
|
||||
var accumulator = initial
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from right to left
|
||||
* to each element with its index in the original array and current accumulator value.
|
||||
*/
|
||||
public inline fun <R> FloatArray.foldRightIndexed(initial: R, operation: (Int, Float, R) -> R): R {
|
||||
var index = lastIndex
|
||||
var accumulator = initial
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from right to left
|
||||
* to each element with its index in the original array and current accumulator value.
|
||||
*/
|
||||
public inline fun <R> IntArray.foldRightIndexed(initial: R, operation: (Int, Int, R) -> R): R {
|
||||
var index = lastIndex
|
||||
var accumulator = initial
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from right to left
|
||||
* to each element with its index in the original array and current accumulator value.
|
||||
*/
|
||||
public inline fun <R> LongArray.foldRightIndexed(initial: R, operation: (Int, Long, R) -> R): R {
|
||||
var index = lastIndex
|
||||
var accumulator = initial
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from right to left
|
||||
* to each element with its index in the original array and current accumulator value.
|
||||
*/
|
||||
public inline fun <R> ShortArray.foldRightIndexed(initial: R, operation: (Int, Short, R) -> R): R {
|
||||
var index = lastIndex
|
||||
var accumulator = initial
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the given [action] on each element.
|
||||
*/
|
||||
@@ -10052,6 +10277,141 @@ public inline fun ShortArray.reduce(operation: (Short, Short) -> Short): Short {
|
||||
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.
|
||||
*/
|
||||
public inline fun <S, T: S> Array<out T>.reduceIndexed(operation: (Int, S, T) -> S): S {
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
var index = 1
|
||||
var accumulator: S = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
accumulator = operation(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 with its index in the original array.
|
||||
*/
|
||||
public inline fun BooleanArray.reduceIndexed(operation: (Int, Boolean, Boolean) -> Boolean): Boolean {
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
var index = 1
|
||||
var accumulator = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
accumulator = operation(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 with its index in the original array.
|
||||
*/
|
||||
public inline fun ByteArray.reduceIndexed(operation: (Int, Byte, Byte) -> Byte): Byte {
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
var index = 1
|
||||
var accumulator = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
accumulator = operation(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 with its index in the original array.
|
||||
*/
|
||||
public inline fun CharArray.reduceIndexed(operation: (Int, Char, Char) -> Char): Char {
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
var index = 1
|
||||
var accumulator = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
accumulator = operation(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 with its index in the original array.
|
||||
*/
|
||||
public inline fun DoubleArray.reduceIndexed(operation: (Int, Double, Double) -> Double): Double {
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
var index = 1
|
||||
var accumulator = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
accumulator = operation(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 with its index in the original array.
|
||||
*/
|
||||
public inline fun FloatArray.reduceIndexed(operation: (Int, Float, Float) -> Float): Float {
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
var index = 1
|
||||
var accumulator = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
accumulator = operation(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 with its index in the original array.
|
||||
*/
|
||||
public inline fun IntArray.reduceIndexed(operation: (Int, Int, Int) -> Int): Int {
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
var index = 1
|
||||
var accumulator = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
accumulator = operation(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 with its index in the original array.
|
||||
*/
|
||||
public inline fun LongArray.reduceIndexed(operation: (Int, Long, Long) -> Long): Long {
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
var index = 1
|
||||
var accumulator = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
accumulator = operation(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 with its index in the original array.
|
||||
*/
|
||||
public inline fun ShortArray.reduceIndexed(operation: (Int, Short, Short) -> Short): Short {
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
var index = 1
|
||||
var accumulator = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
accumulator = operation(index++, accumulator, iterator.next())
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with last element and applying [operation] from right to left to each element and current accumulator value.
|
||||
*/
|
||||
@@ -10169,6 +10529,141 @@ public inline fun ShortArray.reduceRight(operation: (Short, Short) -> Short): Sh
|
||||
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.
|
||||
*/
|
||||
public inline fun <S, T: S> Array<out T>.reduceRightIndexed(operation: (Int, T, S) -> S): S {
|
||||
var index = lastIndex
|
||||
if (index < 0) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
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.
|
||||
*/
|
||||
public inline fun BooleanArray.reduceRightIndexed(operation: (Int, Boolean, Boolean) -> Boolean): Boolean {
|
||||
var index = lastIndex
|
||||
if (index < 0) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
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.
|
||||
*/
|
||||
public inline fun ByteArray.reduceRightIndexed(operation: (Int, Byte, Byte) -> Byte): Byte {
|
||||
var index = lastIndex
|
||||
if (index < 0) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
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.
|
||||
*/
|
||||
public inline fun CharArray.reduceRightIndexed(operation: (Int, Char, Char) -> Char): Char {
|
||||
var index = lastIndex
|
||||
if (index < 0) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
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.
|
||||
*/
|
||||
public inline fun DoubleArray.reduceRightIndexed(operation: (Int, Double, Double) -> Double): Double {
|
||||
var index = lastIndex
|
||||
if (index < 0) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
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.
|
||||
*/
|
||||
public inline fun FloatArray.reduceRightIndexed(operation: (Int, Float, Float) -> Float): Float {
|
||||
var index = lastIndex
|
||||
if (index < 0) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
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.
|
||||
*/
|
||||
public inline fun IntArray.reduceRightIndexed(operation: (Int, Int, Int) -> Int): Int {
|
||||
var index = lastIndex
|
||||
if (index < 0) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
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.
|
||||
*/
|
||||
public inline fun LongArray.reduceRightIndexed(operation: (Int, Long, Long) -> Long): Long {
|
||||
var index = lastIndex
|
||||
if (index < 0) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
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.
|
||||
*/
|
||||
public inline fun ShortArray.reduceRightIndexed(operation: (Int, Short, Short) -> Short): Short {
|
||||
var index = lastIndex
|
||||
if (index < 0) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
var accumulator = get(index--)
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all values produced by [selector] function applied to each element in the array.
|
||||
*/
|
||||
|
||||
@@ -1351,6 +1351,17 @@ public inline fun <T, R> Iterable<T>.fold(initial: R, operation: (R, T) -> R): R
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public inline fun <T, R> Iterable<T>.foldIndexed(initial: R, operation: (Int, R, T) -> R): R {
|
||||
var index = 0
|
||||
var accumulator = initial
|
||||
for (element in this) accumulator = operation(index++, accumulator, element)
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from right to left to each element and current accumulator value.
|
||||
*/
|
||||
@@ -1363,6 +1374,20 @@ public inline fun <T, R> List<T>.foldRight(initial: R, operation: (T, R) -> R):
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from right to left
|
||||
* to each element with its index in the original list and current accumulator value.
|
||||
*/
|
||||
public inline fun <T, R> List<T>.foldRightIndexed(initial: R, operation: (Int, T, R) -> R): R {
|
||||
var index = lastIndex
|
||||
var accumulator = initial
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the given [action] on each element.
|
||||
*/
|
||||
@@ -1502,6 +1527,21 @@ public inline fun <S, T: S> Iterable<T>.reduce(operation: (S, T) -> S): S {
|
||||
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.
|
||||
*/
|
||||
public inline fun <S, T: S> Iterable<T>.reduceIndexed(operation: (Int, S, T) -> S): S {
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
var index = 1
|
||||
var accumulator: S = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
accumulator = operation(index++, accumulator, iterator.next())
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with last element and applying [operation] from right to left to each element and current accumulator value.
|
||||
*/
|
||||
@@ -1515,6 +1555,21 @@ public inline fun <S, T: S> List<T>.reduceRight(operation: (T, S) -> S): S {
|
||||
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.
|
||||
*/
|
||||
public inline fun <S, T: S> List<T>.reduceRightIndexed(operation: (Int, T, S) -> S): S {
|
||||
var index = lastIndex
|
||||
if (index < 0) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
var accumulator: S = get(index--)
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all values produced by [selector] function applied to each element in the collection.
|
||||
*/
|
||||
|
||||
@@ -796,6 +796,17 @@ public inline fun <T, R> Sequence<T>.fold(initial: R, operation: (R, T) -> R): R
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 sequence.
|
||||
*/
|
||||
public inline fun <T, R> Sequence<T>.foldIndexed(initial: R, operation: (Int, R, T) -> R): R {
|
||||
var index = 0
|
||||
var accumulator = initial
|
||||
for (element in this) accumulator = operation(index++, accumulator, element)
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the given [action] on each element.
|
||||
*/
|
||||
@@ -934,6 +945,21 @@ public inline fun <S, T: S> Sequence<T>.reduce(operation: (S, T) -> S): S {
|
||||
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.
|
||||
*/
|
||||
public inline fun <S, T: S> Sequence<T>.reduceIndexed(operation: (Int, S, T) -> S): S {
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
var index = 1
|
||||
var accumulator: S = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
accumulator = operation(index++, accumulator, iterator.next())
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all values produced by [selector] function applied to each element in the sequence.
|
||||
*/
|
||||
|
||||
@@ -831,6 +831,17 @@ public inline fun <R> CharSequence.fold(initial: R, operation: (R, Char) -> R):
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from left to right
|
||||
* to current accumulator value and each character with its index in the original char sequence.
|
||||
*/
|
||||
public inline fun <R> CharSequence.foldIndexed(initial: R, operation: (Int, R, Char) -> R): R {
|
||||
var index = 0
|
||||
var accumulator = initial
|
||||
for (element in this) accumulator = operation(index++, accumulator, element)
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from right to left to each character and current accumulator value.
|
||||
*/
|
||||
@@ -843,6 +854,20 @@ public inline fun <R> CharSequence.foldRight(initial: R, operation: (Char, R) ->
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with [initial] value and applying [operation] from right to left
|
||||
* to each character with its index in the original char sequence and current accumulator value.
|
||||
*/
|
||||
public inline fun <R> CharSequence.foldRightIndexed(initial: R, operation: (Int, Char, R) -> R): R {
|
||||
var index = lastIndex
|
||||
var accumulator = initial
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the given [action] on each character.
|
||||
*/
|
||||
@@ -975,6 +1000,21 @@ public inline fun CharSequence.reduce(operation: (Char, Char) -> Char): 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.
|
||||
*/
|
||||
public inline fun CharSequence.reduceIndexed(operation: (Int, Char, Char) -> Char): Char {
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
var index = 1
|
||||
var accumulator = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
accumulator = operation(index++, accumulator, iterator.next())
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulates value starting with last character and applying [operation] from right to left to each character and current accumulator value.
|
||||
*/
|
||||
@@ -988,6 +1028,21 @@ public inline fun CharSequence.reduceRight(operation: (Char, Char) -> Char): Cha
|
||||
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.
|
||||
*/
|
||||
public inline fun CharSequence.reduceRightIndexed(operation: (Int, Char, Char) -> Char): Char {
|
||||
var index = lastIndex
|
||||
if (index < 0) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
var accumulator = get(index--)
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
return accumulator
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sum of all values produced by [selector] function applied to each character in the char sequence.
|
||||
*/
|
||||
|
||||
@@ -619,6 +619,38 @@ class ArraysTest {
|
||||
|
||||
|
||||
|
||||
@test fun reduceIndexed() {
|
||||
expect(-1) { intArrayOf(1, 2, 3).reduceIndexed { index, a, b -> index + a - b } }
|
||||
expect(-1.toLong()) { longArrayOf(1, 2, 3).reduceIndexed { index, a, b -> index + a - b } }
|
||||
expect(-1F) { floatArrayOf(1F, 2F, 3F).reduceIndexed { index, a, b -> index + a - b } }
|
||||
expect(-1.0) { doubleArrayOf(1.0, 2.0, 3.0).reduceIndexed { index, a, b -> index + a - b } }
|
||||
expect('2') { charArrayOf('1', '3', '2').reduceIndexed { index, a, b -> if (a > b && index == 1) a else b } }
|
||||
expect(true) { booleanArrayOf(true, true, false).reduceIndexed { index, a, b -> a && b || index == 2 } }
|
||||
expect(false) { booleanArrayOf(true, true).reduceIndexed { index, a, b -> a && b && index != 1 } }
|
||||
expect(1.toByte()) { byteArrayOf(3, 2, 1).reduceIndexed { index, a, b -> if (index != 2) (a - b).toByte() else a.toByte() } }
|
||||
expect(1.toShort()) { shortArrayOf(3, 2, 1).reduceIndexed { index, a, b -> if (index != 2) (a - b).toShort() else a.toShort() } }
|
||||
|
||||
assertTrue(assertFails {
|
||||
intArrayOf().reduceIndexed { index, a, b -> a + b }
|
||||
} is UnsupportedOperationException)
|
||||
}
|
||||
|
||||
@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 } }
|
||||
expect(1F) { floatArrayOf(1F, 2F, 3F).reduceRightIndexed { index, a, b -> index + a - b } }
|
||||
expect(1.0) { doubleArrayOf(1.0, 2.0, 3.0).reduceRightIndexed { index, a, b -> index + a - b } }
|
||||
expect('2') { charArrayOf('1', '3', '2').reduceRightIndexed { index, a, b -> if (a > b && index == 0) a else b } }
|
||||
expect(true) { booleanArrayOf(true, true, false).reduceRightIndexed { index, a, b -> a && b || index == 1 } }
|
||||
expect(false) { booleanArrayOf(true, true).reduceRightIndexed { index, a, b -> a && b && index != 0 } }
|
||||
expect(1.toByte()) { byteArrayOf(3, 2, 1).reduceRightIndexed { index, a, b -> if (index != 1) (a - b).toByte() else a.toByte() } }
|
||||
expect(1.toShort()) { shortArrayOf(3, 2, 1).reduceRightIndexed { index, a, b -> if (index != 1) (a - b).toShort() else a.toShort() } }
|
||||
|
||||
assertTrue(assertFails {
|
||||
intArrayOf().reduceRightIndexed { index, a, b -> a + b }
|
||||
} is UnsupportedOperationException)
|
||||
}
|
||||
|
||||
@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 } }
|
||||
|
||||
@@ -79,6 +79,63 @@ class CollectionTest {
|
||||
}
|
||||
}
|
||||
|
||||
@test fun foldIndexed() {
|
||||
expect(42) {
|
||||
val numbers = listOf(1, 2, 3, 4)
|
||||
numbers.foldIndexed(0) { index, a, b -> index * (a + b) }
|
||||
}
|
||||
|
||||
expect(0) {
|
||||
val numbers = arrayListOf<Int>()
|
||||
numbers.foldIndexed(0) { index, a, b -> index * (a + b) }
|
||||
}
|
||||
|
||||
expect("11234") {
|
||||
val numbers = listOf(1, 2, 3, 4)
|
||||
numbers.map { it.toString() }.foldIndexed("") { index, a, b -> if (index == 0) a + b + b else a + b }
|
||||
}
|
||||
}
|
||||
|
||||
@test fun foldIndexedWithDifferentTypes() {
|
||||
expect(10) {
|
||||
val numbers = listOf("a", "ab", "abc")
|
||||
numbers.foldIndexed(1) { index, a, b -> a + b.length + index }
|
||||
}
|
||||
|
||||
expect("11223344") {
|
||||
val numbers = listOf(1, 2, 3, 4)
|
||||
numbers.foldIndexed("") { index, a, b -> a + b + (index + 1) }
|
||||
}
|
||||
}
|
||||
|
||||
@test fun foldIndexedWithNonCommutativeOperation() {
|
||||
expect(4) {
|
||||
val numbers = listOf(1, 2, 3)
|
||||
numbers.foldIndexed(7) { index, a, b -> index + a - b }
|
||||
}
|
||||
}
|
||||
|
||||
@test fun foldRightIndexed() {
|
||||
expect("12343210") {
|
||||
val numbers = listOf(1, 2, 3, 4)
|
||||
numbers.map { it.toString() }.foldRightIndexed("") { index, a, b -> a + b + index }
|
||||
}
|
||||
}
|
||||
|
||||
@test fun foldRightIndexedWithDifferentTypes() {
|
||||
expect("12343210") {
|
||||
val numbers = listOf(1, 2, 3, 4)
|
||||
numbers.foldRightIndexed("") { index, a, b -> "" + a + b + index }
|
||||
}
|
||||
}
|
||||
|
||||
@test fun foldRightIndexedWithNonCommutativeOperation() {
|
||||
expect(-4) {
|
||||
val numbers = listOf(1, 2, 3)
|
||||
numbers.foldRightIndexed(7) { index, a, b -> index + a - b }
|
||||
}
|
||||
}
|
||||
|
||||
@test fun fold() {
|
||||
// lets calculate the sum of some numbers
|
||||
expect(10) {
|
||||
@@ -160,6 +217,32 @@ class CollectionTest {
|
||||
assertEquals(listOf("something"), pair.second, "pair.second")
|
||||
}
|
||||
|
||||
@test fun reduceIndexed() {
|
||||
expect("123") {
|
||||
val list = listOf("1", "2", "3", "4")
|
||||
list.reduceIndexed { index, a, b -> if (index == 3) a else a + b }
|
||||
}
|
||||
|
||||
// TODO replace with more accurate version when KT-5987 will be fixed
|
||||
// failsWith(javaClass<UnsupportedOperationException>()) {
|
||||
assertFails {
|
||||
run { arrayListOf<Int>().reduceIndexed { index, a, b -> a + b } }
|
||||
}
|
||||
}
|
||||
|
||||
@test fun reduceRightIndexed() {
|
||||
expect("234") {
|
||||
val list = listOf("1", "2", "3", "4")
|
||||
list.reduceRightIndexed { index, a, b -> if (index == 0) b else a + b }
|
||||
}
|
||||
|
||||
// TODO replace with more accurate version when KT-5987 will be fixed
|
||||
// failsWith(javaClass<UnsupportedOperationException>()) {
|
||||
assertFails {
|
||||
run { arrayListOf<Int>().reduceRightIndexed { index, a, b -> a + b } }
|
||||
}
|
||||
}
|
||||
|
||||
@test fun reduce() {
|
||||
expect("1234") {
|
||||
val list = listOf("1", "2", "3", "4")
|
||||
|
||||
@@ -859,6 +859,24 @@ class StringTest {
|
||||
assertEquals(data.toString(), data.foldRight("", { s, c -> "" + s + c }))
|
||||
}
|
||||
|
||||
@test fun reduceIndexed() = withOneCharSequenceArg { arg1 ->
|
||||
// get the 3rd character
|
||||
assertEquals('c', arg1("bacfd").reduceIndexed { index, v, c -> if (index == 2) c else v })
|
||||
|
||||
assertTrue(assertFails {
|
||||
arg1("").reduceIndexed { index, a, b -> '\n' }
|
||||
} is UnsupportedOperationException)
|
||||
}
|
||||
|
||||
@test fun reduceRightIndexed() = withOneCharSequenceArg { arg1 ->
|
||||
// get the 3rd character
|
||||
assertEquals('c', arg1("bacfd").reduceRightIndexed { index, c, v -> if (index == 2) c else v })
|
||||
|
||||
assertTrue(assertFails {
|
||||
arg1("").reduceRightIndexed { index, a, b -> '\n' }
|
||||
} is UnsupportedOperationException)
|
||||
}
|
||||
|
||||
@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 })
|
||||
|
||||
@@ -349,6 +349,53 @@ fun aggregates(): List<GenericFunction> {
|
||||
body(Maps) { "return entries.maxWith(comparator)" }
|
||||
}
|
||||
|
||||
templates add f("foldIndexed(initial: R, operation: (Int, R, T) -> R)") {
|
||||
inline(true)
|
||||
|
||||
include(CharSequences)
|
||||
doc { f ->
|
||||
"""
|
||||
Accumulates value starting with [initial] value and applying [operation] from left to right
|
||||
to current accumulator value and each ${f.element} with its index in the original ${f.collection}.
|
||||
"""
|
||||
}
|
||||
typeParam("R")
|
||||
returns("R")
|
||||
body {
|
||||
"""
|
||||
var index = 0
|
||||
var accumulator = initial
|
||||
for (element in this) accumulator = operation(index++, accumulator, element)
|
||||
return accumulator
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
templates add f("foldRightIndexed(initial: R, operation: (Int, T, R) -> R)") {
|
||||
inline(true)
|
||||
|
||||
only(CharSequences, Lists, ArraysOfObjects, ArraysOfPrimitives)
|
||||
doc { f ->
|
||||
"""
|
||||
Accumulates value starting with [initial] value and applying [operation] from right to left
|
||||
to each ${f.element} with its index in the original ${f.collection} and current accumulator value.
|
||||
"""
|
||||
}
|
||||
typeParam("R")
|
||||
returns("R")
|
||||
body {
|
||||
"""
|
||||
var index = lastIndex
|
||||
var accumulator = initial
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
return accumulator
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
templates add f("fold(initial: R, operation: (R, T) -> R)") {
|
||||
inline(true)
|
||||
|
||||
@@ -384,6 +431,116 @@ fun aggregates(): List<GenericFunction> {
|
||||
}
|
||||
}
|
||||
|
||||
templates add f("reduceIndexed(operation: (Int, T, T) -> T)") {
|
||||
inline(true)
|
||||
include(CharSequences)
|
||||
exclude(ArraysOfObjects, Iterables, Sequences)
|
||||
|
||||
doc { f ->
|
||||
"""
|
||||
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("T")
|
||||
body {
|
||||
"""
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
|
||||
var index = 1
|
||||
var accumulator = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
accumulator = operation(index++, accumulator, iterator.next())
|
||||
}
|
||||
return accumulator
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
templates add f("reduceIndexed(operation: (Int, S, T) -> S)") {
|
||||
inline(true)
|
||||
only(ArraysOfObjects, Iterables, Sequences)
|
||||
|
||||
doc { f ->
|
||||
"""
|
||||
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}.
|
||||
"""
|
||||
}
|
||||
typeParam("S")
|
||||
typeParam("T: S")
|
||||
returns("S")
|
||||
body {
|
||||
"""
|
||||
val iterator = this.iterator()
|
||||
if (!iterator.hasNext()) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
|
||||
var index = 1
|
||||
var accumulator: S = iterator.next()
|
||||
while (iterator.hasNext()) {
|
||||
accumulator = operation(index++, accumulator, iterator.next())
|
||||
}
|
||||
return accumulator
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
templates add f("reduceRightIndexed(operation: (Int, T, T) -> T)") {
|
||||
inline(true)
|
||||
|
||||
only(CharSequences, ArraysOfPrimitives)
|
||||
doc { f ->
|
||||
"""
|
||||
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("T")
|
||||
body {
|
||||
"""
|
||||
var index = lastIndex
|
||||
if (index < 0) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
|
||||
var accumulator = get(index--)
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
|
||||
return accumulator
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
templates add f("reduceRightIndexed(operation: (Int, T, S) -> S)") {
|
||||
inline(true)
|
||||
|
||||
only(Lists, ArraysOfObjects)
|
||||
doc { f ->
|
||||
"""
|
||||
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.
|
||||
"""
|
||||
}
|
||||
typeParam("S")
|
||||
typeParam("T: S")
|
||||
returns("S")
|
||||
body {
|
||||
"""
|
||||
var index = lastIndex
|
||||
if (index < 0) throw UnsupportedOperationException("Empty iterable can't be reduced.")
|
||||
|
||||
var accumulator: S = get(index--)
|
||||
while (index >= 0) {
|
||||
accumulator = operation(index, get(index), accumulator)
|
||||
--index
|
||||
}
|
||||
|
||||
return accumulator
|
||||
"""
|
||||
}
|
||||
}
|
||||
|
||||
templates add f("reduce(operation: (T, T) -> T)") {
|
||||
inline(true)
|
||||
|
||||
Reference in New Issue
Block a user