KT-33761 Add reduceRightOrNull
This commit is contained in:
committed by
Ilya Gorbunov
parent
f5d696d3c4
commit
06008c40ab
@@ -13136,6 +13136,141 @@ public inline fun CharArray.reduceRightIndexed(operation: (index: Int, Char, acc
|
|||||||
return 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 array is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
public inline fun <S, T : S> Array<out T>.reduceRightOrNull(operation: (T, acc: S) -> S): S? {
|
||||||
|
var index = lastIndex
|
||||||
|
if (index < 0) return null
|
||||||
|
var accumulator: S = get(index--)
|
||||||
|
while (index >= 0) {
|
||||||
|
accumulator = operation(get(index--), 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 array is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
public inline fun ByteArray.reduceRightOrNull(operation: (Byte, acc: Byte) -> Byte): Byte? {
|
||||||
|
var index = lastIndex
|
||||||
|
if (index < 0) return null
|
||||||
|
var accumulator = get(index--)
|
||||||
|
while (index >= 0) {
|
||||||
|
accumulator = operation(get(index--), 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 array is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
public inline fun ShortArray.reduceRightOrNull(operation: (Short, acc: Short) -> Short): Short? {
|
||||||
|
var index = lastIndex
|
||||||
|
if (index < 0) return null
|
||||||
|
var accumulator = get(index--)
|
||||||
|
while (index >= 0) {
|
||||||
|
accumulator = operation(get(index--), 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 array is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
public inline fun IntArray.reduceRightOrNull(operation: (Int, acc: Int) -> Int): Int? {
|
||||||
|
var index = lastIndex
|
||||||
|
if (index < 0) return null
|
||||||
|
var accumulator = get(index--)
|
||||||
|
while (index >= 0) {
|
||||||
|
accumulator = operation(get(index--), 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 array is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
public inline fun LongArray.reduceRightOrNull(operation: (Long, acc: Long) -> Long): Long? {
|
||||||
|
var index = lastIndex
|
||||||
|
if (index < 0) return null
|
||||||
|
var accumulator = get(index--)
|
||||||
|
while (index >= 0) {
|
||||||
|
accumulator = operation(get(index--), 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 array is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
public inline fun FloatArray.reduceRightOrNull(operation: (Float, acc: Float) -> Float): Float? {
|
||||||
|
var index = lastIndex
|
||||||
|
if (index < 0) return null
|
||||||
|
var accumulator = get(index--)
|
||||||
|
while (index >= 0) {
|
||||||
|
accumulator = operation(get(index--), 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 array is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
public inline fun DoubleArray.reduceRightOrNull(operation: (Double, acc: Double) -> Double): Double? {
|
||||||
|
var index = lastIndex
|
||||||
|
if (index < 0) return null
|
||||||
|
var accumulator = get(index--)
|
||||||
|
while (index >= 0) {
|
||||||
|
accumulator = operation(get(index--), 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 array is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
public inline fun BooleanArray.reduceRightOrNull(operation: (Boolean, acc: Boolean) -> Boolean): Boolean? {
|
||||||
|
var index = lastIndex
|
||||||
|
if (index < 0) return null
|
||||||
|
var accumulator = get(index--)
|
||||||
|
while (index >= 0) {
|
||||||
|
accumulator = operation(get(index--), 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 array is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
public inline fun CharArray.reduceRightOrNull(operation: (Char, acc: Char) -> Char): Char? {
|
||||||
|
var index = lastIndex
|
||||||
|
if (index < 0) return null
|
||||||
|
var accumulator = get(index--)
|
||||||
|
while (index >= 0) {
|
||||||
|
accumulator = operation(get(index--), accumulator)
|
||||||
|
}
|
||||||
|
return accumulator
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sum of all values produced by [selector] function applied to each element in the array.
|
* Returns the sum of all values produced by [selector] function applied to each element in the array.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1913,6 +1913,22 @@ public inline fun <S, T : S> List<T>.reduceRightIndexed(operation: (index: Int,
|
|||||||
return 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.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
public inline fun <S, T : S> List<T>.reduceRightOrNull(operation: (T, acc: S) -> S): S? {
|
||||||
|
val iterator = listIterator(size)
|
||||||
|
if (!iterator.hasPrevious())
|
||||||
|
return null
|
||||||
|
var accumulator: S = iterator.previous()
|
||||||
|
while (iterator.hasPrevious()) {
|
||||||
|
accumulator = operation(iterator.previous(), accumulator)
|
||||||
|
}
|
||||||
|
return accumulator
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sum of all values produced by [selector] function applied to each element in the collection.
|
* Returns the sum of all values produced by [selector] function applied to each element in the collection.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1240,6 +1240,21 @@ public inline fun CharSequence.reduceRightIndexed(operation: (index: Int, Char,
|
|||||||
return accumulator
|
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.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
public inline fun CharSequence.reduceRightOrNull(operation: (Char, acc: Char) -> Char): Char? {
|
||||||
|
var index = lastIndex
|
||||||
|
if (index < 0) return null
|
||||||
|
var accumulator = get(index--)
|
||||||
|
while (index >= 0) {
|
||||||
|
accumulator = operation(get(index--), accumulator)
|
||||||
|
}
|
||||||
|
return accumulator
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sum of all values produced by [selector] function applied to each character in the char sequence.
|
* Returns the sum of all values produced by [selector] function applied to each character in the char sequence.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5830,6 +5830,74 @@ public inline fun UShortArray.reduceRightIndexed(operation: (index: Int, UShort,
|
|||||||
return 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 array is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
|
@kotlin.internal.InlineOnly
|
||||||
|
public inline fun UIntArray.reduceRightOrNull(operation: (UInt, acc: UInt) -> UInt): UInt? {
|
||||||
|
var index = lastIndex
|
||||||
|
if (index < 0) return null
|
||||||
|
var accumulator = get(index--)
|
||||||
|
while (index >= 0) {
|
||||||
|
accumulator = operation(get(index--), 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 array is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
|
@kotlin.internal.InlineOnly
|
||||||
|
public inline fun ULongArray.reduceRightOrNull(operation: (ULong, acc: ULong) -> ULong): ULong? {
|
||||||
|
var index = lastIndex
|
||||||
|
if (index < 0) return null
|
||||||
|
var accumulator = get(index--)
|
||||||
|
while (index >= 0) {
|
||||||
|
accumulator = operation(get(index--), 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 array is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
|
@kotlin.internal.InlineOnly
|
||||||
|
public inline fun UByteArray.reduceRightOrNull(operation: (UByte, acc: UByte) -> UByte): UByte? {
|
||||||
|
var index = lastIndex
|
||||||
|
if (index < 0) return null
|
||||||
|
var accumulator = get(index--)
|
||||||
|
while (index >= 0) {
|
||||||
|
accumulator = operation(get(index--), 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 array is empty.
|
||||||
|
*/
|
||||||
|
@SinceKotlin("1.3")
|
||||||
|
@ExperimentalStdlibApi
|
||||||
|
@ExperimentalUnsignedTypes
|
||||||
|
@kotlin.internal.InlineOnly
|
||||||
|
public inline fun UShortArray.reduceRightOrNull(operation: (UShort, acc: UShort) -> UShort): UShort? {
|
||||||
|
var index = lastIndex
|
||||||
|
if (index < 0) return null
|
||||||
|
var accumulator = get(index--)
|
||||||
|
while (index >= 0) {
|
||||||
|
accumulator = operation(get(index--), accumulator)
|
||||||
|
}
|
||||||
|
return accumulator
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the sum of all values produced by [selector] function applied to each element in the array.
|
* Returns the sum of all values produced by [selector] function applied to each element in the array.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1036,6 +1036,20 @@ class ArraysTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test fun reduceRightOrNull() {
|
||||||
|
expect(2) { intArrayOf(1, 2, 3).reduceRightOrNull { a, b -> a - b } }
|
||||||
|
expect(2.toLong()) { longArrayOf(1, 2, 3).reduceRightOrNull { a, b -> a - b } }
|
||||||
|
expect(2F) { floatArrayOf(1F, 2F, 3F).reduceRightOrNull { a, b -> a - b } }
|
||||||
|
expect(2.0) { doubleArrayOf(1.0, 2.0, 3.0).reduceRightOrNull { a, b -> a - b } }
|
||||||
|
expect('3') { charArrayOf('1', '3', '2').reduceRightOrNull { a, b -> if (a > b) a else b } }
|
||||||
|
expect(false) { booleanArrayOf(true, true, false).reduceRightOrNull { a, b -> a && b } }
|
||||||
|
expect(true) { booleanArrayOf(true, true).reduceRightOrNull { a, b -> a && b } }
|
||||||
|
expect(2.toByte()) { byteArrayOf(1, 2, 3).reduceRightOrNull { a, b -> (a - b).toByte() } }
|
||||||
|
expect(2.toShort()) { shortArrayOf(1, 2, 3).reduceRightOrNull { a, b -> (a - b).toShort() } }
|
||||||
|
|
||||||
|
expect(null, { intArrayOf().reduceRightOrNull { a, b -> a + b } })
|
||||||
|
}
|
||||||
|
|
||||||
@Test fun reverseInPlace() {
|
@Test fun reverseInPlace() {
|
||||||
|
|
||||||
fun <TArray, T> doTest(build: Iterable<Int>.() -> TArray, reverse: TArray.() -> Unit, snapshot: TArray.() -> List<T>) {
|
fun <TArray, T> doTest(build: Iterable<Int>.() -> TArray, reverse: TArray.() -> Unit, snapshot: TArray.() -> List<T>) {
|
||||||
|
|||||||
@@ -335,6 +335,15 @@ class CollectionTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test fun reduceRightOrNull() {
|
||||||
|
expect("1234") {
|
||||||
|
val list = listOf("1", "2", "3", "4")
|
||||||
|
list.reduceRightOrNull { a, b -> a + b }
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(null, { arrayListOf<Int>().reduceRightOrNull { a, b -> a + b } })
|
||||||
|
}
|
||||||
|
|
||||||
@Test fun groupBy() {
|
@Test fun groupBy() {
|
||||||
val words = listOf("a", "abc", "ab", "def", "abcd")
|
val words = listOf("a", "abc", "ab", "def", "abcd")
|
||||||
val byLength = words.groupBy { it.length }
|
val byLength = words.groupBy { it.length }
|
||||||
|
|||||||
@@ -961,6 +961,70 @@ object Aggregates : TemplateGroupBase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val f_reduceRightOrNull = fn("reduceRightOrNull(operation: (T, acc: T) -> T)") {
|
||||||
|
include(CharSequences, ArraysOfPrimitives, ArraysOfUnsigned)
|
||||||
|
} builder {
|
||||||
|
since("1.3")
|
||||||
|
annotation("@ExperimentalStdlibApi")
|
||||||
|
inline()
|
||||||
|
specialFor(ArraysOfUnsigned) { inlineOnly() }
|
||||||
|
|
||||||
|
doc { "Accumulates value starting with last ${f.element} and applying [operation] from right to left to each ${f.element} and current accumulator value. Returns null if the ${f.collection} is empty." }
|
||||||
|
returns("T?")
|
||||||
|
body {
|
||||||
|
"""
|
||||||
|
var index = lastIndex
|
||||||
|
if (index < 0) return null
|
||||||
|
|
||||||
|
var accumulator = get(index--)
|
||||||
|
while (index >= 0) {
|
||||||
|
accumulator = operation(get(index--), accumulator)
|
||||||
|
}
|
||||||
|
|
||||||
|
return accumulator
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val f_reduceRightOrNullSuper = fn("reduceRightOrNull(operation: (T, acc: S) -> S)") {
|
||||||
|
include(Lists, ArraysOfObjects)
|
||||||
|
} builder {
|
||||||
|
since("1.3")
|
||||||
|
annotation("@ExperimentalStdlibApi")
|
||||||
|
inline()
|
||||||
|
doc { "Accumulates value starting with last ${f.element} and applying [operation] from right to left to each ${f.element} and current accumulator value. Returns null if the ${f.collection} is empty." }
|
||||||
|
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(get(index--), accumulator)
|
||||||
|
}
|
||||||
|
|
||||||
|
return accumulator
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
body(Lists) {
|
||||||
|
"""
|
||||||
|
val iterator = listIterator(size)
|
||||||
|
if (!iterator.hasPrevious())
|
||||||
|
return null
|
||||||
|
|
||||||
|
var accumulator: S = iterator.previous()
|
||||||
|
while (iterator.hasPrevious()) {
|
||||||
|
accumulator = operation(iterator.previous(), accumulator)
|
||||||
|
}
|
||||||
|
|
||||||
|
return accumulator
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val f_onEach = fn("onEach(action: (T) -> Unit)") {
|
val f_onEach = fn("onEach(action: (T) -> Unit)") {
|
||||||
include(Iterables, Maps, CharSequences, Sequences)
|
include(Iterables, Maps, CharSequences, Sequences)
|
||||||
} builder {
|
} builder {
|
||||||
|
|||||||
Reference in New Issue
Block a user