From 893021f22b6bdd409f917c724efb536500fcb43f Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Tue, 14 Apr 2020 14:34:02 +0300 Subject: [PATCH] Introduce runningFold and runningReduce operations runningFold is a synonym for scan, runningReduce replaces scanReduce. #KT-38060 --- .../stdlib/common/src/generated/_Arrays.kt | 722 ++++++++++++++---- .../common/src/generated/_Collections.kt | 74 +- .../stdlib/common/src/generated/_Sequences.kt | 86 ++- .../stdlib/common/src/generated/_Strings.kt | 77 +- .../stdlib/common/src/generated/_UArrays.kt | 644 ++++++++++------ .../test/samples/collections/collections.kt | 17 +- .../stdlib/test/collections/ArraysTest.kt | 132 +++- .../stdlib/test/collections/CollectionTest.kt | 10 +- .../stdlib/test/collections/SequenceTest.kt | 30 +- .../test/collections/UnsignedArraysTest.kt | 64 +- libraries/stdlib/test/text/StringTest.kt | 32 +- .../kotlin-stdlib-runtime-merged.txt | 16 + .../src/templates/Aggregates.kt | 163 +++- 13 files changed, 1551 insertions(+), 516 deletions(-) diff --git a/libraries/stdlib/common/src/generated/_Arrays.kt b/libraries/stdlib/common/src/generated/_Arrays.kt index 7a9c4dad824..069e93ac246 100644 --- a/libraries/stdlib/common/src/generated/_Arrays.kt +++ b/libraries/stdlib/common/src/generated/_Arrays.kt @@ -14986,11 +14986,10 @@ public inline fun CharArray.reduceRightOrNull(operation: (Char, acc: Char) -> Ch * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi -public inline fun Array.scan(initial: R, operation: (acc: R, T) -> R): List { +@SinceKotlin("1.4") +public inline fun Array.runningFold(initial: R, operation: (acc: R, T) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15010,12 +15009,11 @@ public inline fun Array.scan(initial: R, operation: (acc: R, T) -> * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun ByteArray.scan(initial: R, operation: (acc: R, Byte) -> R): List { +public inline fun ByteArray.runningFold(initial: R, operation: (acc: R, Byte) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15035,12 +15033,11 @@ public inline fun ByteArray.scan(initial: R, operation: (acc: R, Byte) -> R) * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun ShortArray.scan(initial: R, operation: (acc: R, Short) -> R): List { +public inline fun ShortArray.runningFold(initial: R, operation: (acc: R, Short) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15060,12 +15057,11 @@ public inline fun ShortArray.scan(initial: R, operation: (acc: R, Short) -> * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun IntArray.scan(initial: R, operation: (acc: R, Int) -> R): List { +public inline fun IntArray.runningFold(initial: R, operation: (acc: R, Int) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15085,12 +15081,11 @@ public inline fun IntArray.scan(initial: R, operation: (acc: R, Int) -> R): * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun LongArray.scan(initial: R, operation: (acc: R, Long) -> R): List { +public inline fun LongArray.runningFold(initial: R, operation: (acc: R, Long) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15110,12 +15105,11 @@ public inline fun LongArray.scan(initial: R, operation: (acc: R, Long) -> R) * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun FloatArray.scan(initial: R, operation: (acc: R, Float) -> R): List { +public inline fun FloatArray.runningFold(initial: R, operation: (acc: R, Float) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15135,12 +15129,11 @@ public inline fun FloatArray.scan(initial: R, operation: (acc: R, Float) -> * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun DoubleArray.scan(initial: R, operation: (acc: R, Double) -> R): List { +public inline fun DoubleArray.runningFold(initial: R, operation: (acc: R, Double) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15160,12 +15153,11 @@ public inline fun DoubleArray.scan(initial: R, operation: (acc: R, Double) - * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun BooleanArray.scan(initial: R, operation: (acc: R, Boolean) -> R): List { +public inline fun BooleanArray.runningFold(initial: R, operation: (acc: R, Boolean) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15185,12 +15177,11 @@ public inline fun BooleanArray.scan(initial: R, operation: (acc: R, Boolean) * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun CharArray.scan(initial: R, operation: (acc: R, Char) -> R): List { +public inline fun CharArray.runningFold(initial: R, operation: (acc: R, Char) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15211,11 +15202,10 @@ public inline fun CharArray.scan(initial: R, operation: (acc: R, Char) -> R) * @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.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi -public inline fun Array.scanIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): List { +@SinceKotlin("1.4") +public inline fun Array.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15236,12 +15226,11 @@ public inline fun Array.scanIndexed(initial: R, operation: (index: * @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.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun ByteArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Byte) -> R): List { +public inline fun ByteArray.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, Byte) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15262,12 +15251,11 @@ public inline fun ByteArray.scanIndexed(initial: R, operation: (index: Int, * @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.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun ShortArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Short) -> R): List { +public inline fun ShortArray.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, Short) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15288,12 +15276,11 @@ public inline fun ShortArray.scanIndexed(initial: R, operation: (index: Int, * @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.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun IntArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Int) -> R): List { +public inline fun IntArray.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, Int) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15314,12 +15301,11 @@ public inline fun IntArray.scanIndexed(initial: R, operation: (index: Int, a * @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.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun LongArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Long) -> R): List { +public inline fun LongArray.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, Long) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15340,12 +15326,11 @@ public inline fun LongArray.scanIndexed(initial: R, operation: (index: Int, * @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.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun FloatArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Float) -> R): List { +public inline fun FloatArray.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, Float) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15366,12 +15351,11 @@ public inline fun FloatArray.scanIndexed(initial: R, operation: (index: Int, * @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.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun DoubleArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Double) -> R): List { +public inline fun DoubleArray.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, Double) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15392,12 +15376,11 @@ public inline fun DoubleArray.scanIndexed(initial: R, operation: (index: Int * @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.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun BooleanArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Boolean) -> R): List { +public inline fun BooleanArray.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, Boolean) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15418,12 +15401,11 @@ public inline fun BooleanArray.scanIndexed(initial: R, operation: (index: In * @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.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun CharArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Char) -> R): List { +public inline fun CharArray.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, Char) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -15443,11 +15425,11 @@ public inline fun CharArray.scanIndexed(initial: R, operation: (index: Int, * * @param [operation] function that takes current accumulator value and the element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ @SinceKotlin("1.3") @ExperimentalStdlibApi -public inline fun Array.scanReduce(operation: (acc: S, T) -> S): List { +public inline fun Array.runningReduce(operation: (acc: S, T) -> S): List { if (isEmpty()) return emptyList() var accumulator: S = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15464,12 +15446,11 @@ public inline fun Array.scanReduce(operation: (acc: S, T) -> S * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun ByteArray.scanReduce(operation: (acc: Byte, Byte) -> Byte): List { +public inline fun ByteArray.runningReduce(operation: (acc: Byte, Byte) -> Byte): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15486,12 +15467,11 @@ public inline fun ByteArray.scanReduce(operation: (acc: Byte, Byte) -> Byte): Li * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun ShortArray.scanReduce(operation: (acc: Short, Short) -> Short): List { +public inline fun ShortArray.runningReduce(operation: (acc: Short, Short) -> Short): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15508,12 +15488,11 @@ public inline fun ShortArray.scanReduce(operation: (acc: Short, Short) -> Short) * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun IntArray.scanReduce(operation: (acc: Int, Int) -> Int): List { +public inline fun IntArray.runningReduce(operation: (acc: Int, Int) -> Int): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15530,12 +15509,11 @@ public inline fun IntArray.scanReduce(operation: (acc: Int, Int) -> Int): List Long): List { +public inline fun LongArray.runningReduce(operation: (acc: Long, Long) -> Long): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15552,12 +15530,11 @@ public inline fun LongArray.scanReduce(operation: (acc: Long, Long) -> Long): Li * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun FloatArray.scanReduce(operation: (acc: Float, Float) -> Float): List { +public inline fun FloatArray.runningReduce(operation: (acc: Float, Float) -> Float): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15574,12 +15551,11 @@ public inline fun FloatArray.scanReduce(operation: (acc: Float, Float) -> Float) * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun DoubleArray.scanReduce(operation: (acc: Double, Double) -> Double): List { +public inline fun DoubleArray.runningReduce(operation: (acc: Double, Double) -> Double): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15596,12 +15572,11 @@ public inline fun DoubleArray.scanReduce(operation: (acc: Double, Double) -> Dou * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun BooleanArray.scanReduce(operation: (acc: Boolean, Boolean) -> Boolean): List { +public inline fun BooleanArray.runningReduce(operation: (acc: Boolean, Boolean) -> Boolean): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15618,12 +15593,11 @@ public inline fun BooleanArray.scanReduce(operation: (acc: Boolean, Boolean) -> * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun CharArray.scanReduce(operation: (acc: Char, Char) -> Char): List { +public inline fun CharArray.runningReduce(operation: (acc: Char, Char) -> Char): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15644,11 +15618,10 @@ public inline fun CharArray.scanReduce(operation: (acc: Char, Char) -> Char): Li * @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.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi -public inline fun Array.scanReduceIndexed(operation: (index: Int, acc: S, T) -> S): List { +@SinceKotlin("1.4") +public inline fun Array.runningReduceIndexed(operation: (index: Int, acc: S, T) -> S): List { if (isEmpty()) return emptyList() var accumulator: S = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15666,12 +15639,11 @@ public inline fun Array.scanReduceIndexed(operation: (index: I * @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.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun ByteArray.scanReduceIndexed(operation: (index: Int, acc: Byte, Byte) -> Byte): List { +public inline fun ByteArray.runningReduceIndexed(operation: (index: Int, acc: Byte, Byte) -> Byte): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15689,12 +15661,11 @@ public inline fun ByteArray.scanReduceIndexed(operation: (index: Int, acc: Byte, * @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.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun ShortArray.scanReduceIndexed(operation: (index: Int, acc: Short, Short) -> Short): List { +public inline fun ShortArray.runningReduceIndexed(operation: (index: Int, acc: Short, Short) -> Short): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15712,12 +15683,11 @@ public inline fun ShortArray.scanReduceIndexed(operation: (index: Int, acc: Shor * @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.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun IntArray.scanReduceIndexed(operation: (index: Int, acc: Int, Int) -> Int): List { +public inline fun IntArray.runningReduceIndexed(operation: (index: Int, acc: Int, Int) -> Int): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15735,12 +15705,11 @@ public inline fun IntArray.scanReduceIndexed(operation: (index: Int, acc: Int, I * @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.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun LongArray.scanReduceIndexed(operation: (index: Int, acc: Long, Long) -> Long): List { +public inline fun LongArray.runningReduceIndexed(operation: (index: Int, acc: Long, Long) -> Long): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15758,12 +15727,11 @@ public inline fun LongArray.scanReduceIndexed(operation: (index: Int, acc: Long, * @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.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun FloatArray.scanReduceIndexed(operation: (index: Int, acc: Float, Float) -> Float): List { +public inline fun FloatArray.runningReduceIndexed(operation: (index: Int, acc: Float, Float) -> Float): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15781,12 +15749,11 @@ public inline fun FloatArray.scanReduceIndexed(operation: (index: Int, acc: Floa * @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.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun DoubleArray.scanReduceIndexed(operation: (index: Int, acc: Double, Double) -> Double): List { +public inline fun DoubleArray.runningReduceIndexed(operation: (index: Int, acc: Double, Double) -> Double): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15804,12 +15771,11 @@ public inline fun DoubleArray.scanReduceIndexed(operation: (index: Int, acc: Dou * @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.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun BooleanArray.scanReduceIndexed(operation: (index: Int, acc: Boolean, Boolean) -> Boolean): List { +public inline fun BooleanArray.runningReduceIndexed(operation: (index: Int, acc: Boolean, Boolean) -> Boolean): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15827,12 +15793,11 @@ public inline fun BooleanArray.scanReduceIndexed(operation: (index: Int, acc: Bo * @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.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @kotlin.internal.InlineOnly -public inline fun CharArray.scanReduceIndexed(operation: (index: Int, acc: Char, Char) -> Char): List { +public inline fun CharArray.runningReduceIndexed(operation: (index: Int, acc: Char, Char) -> Char): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(size).apply { add(accumulator) } @@ -15843,6 +15808,479 @@ public inline fun CharArray.scanReduceIndexed(operation: (index: Int, acc: Char, return result } +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public inline fun Array.scan(initial: R, operation: (acc: R, T) -> R): List { + return runningFold(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun ByteArray.scan(initial: R, operation: (acc: R, Byte) -> R): List { + return runningFold(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun ShortArray.scan(initial: R, operation: (acc: R, Short) -> R): List { + return runningFold(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun IntArray.scan(initial: R, operation: (acc: R, Int) -> R): List { + return runningFold(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun LongArray.scan(initial: R, operation: (acc: R, Long) -> R): List { + return runningFold(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun FloatArray.scan(initial: R, operation: (acc: R, Float) -> R): List { + return runningFold(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun DoubleArray.scan(initial: R, operation: (acc: R, Double) -> R): List { + return runningFold(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun BooleanArray.scan(initial: R, operation: (acc: R, Boolean) -> R): List { + return runningFold(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun CharArray.scan(initial: R, operation: (acc: R, Char) -> R): List { + return runningFold(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public inline fun Array.scanIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): List { + return runningFoldIndexed(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun ByteArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Byte) -> R): List { + return runningFoldIndexed(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun ShortArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Short) -> R): List { + return runningFoldIndexed(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun IntArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Int) -> R): List { + return runningFoldIndexed(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun LongArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Long) -> R): List { + return runningFoldIndexed(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun FloatArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Float) -> R): List { + return runningFoldIndexed(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun DoubleArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Double) -> R): List { + return runningFoldIndexed(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun BooleanArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Boolean) -> R): List { + return runningFoldIndexed(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun CharArray.scanIndexed(initial: R, operation: (index: Int, acc: R, Char) -> R): List { + return runningFoldIndexed(initial, operation) +} + +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public inline fun Array.scanReduce(operation: (acc: S, T) -> S): List { + return runningReduce(operation) +} + +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun ByteArray.scanReduce(operation: (acc: Byte, Byte) -> Byte): List { + return runningReduce(operation) +} + +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun ShortArray.scanReduce(operation: (acc: Short, Short) -> Short): List { + return runningReduce(operation) +} + +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun IntArray.scanReduce(operation: (acc: Int, Int) -> Int): List { + return runningReduce(operation) +} + +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun LongArray.scanReduce(operation: (acc: Long, Long) -> Long): List { + return runningReduce(operation) +} + +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun FloatArray.scanReduce(operation: (acc: Float, Float) -> Float): List { + return runningReduce(operation) +} + +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun DoubleArray.scanReduce(operation: (acc: Double, Double) -> Double): List { + return runningReduce(operation) +} + +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun BooleanArray.scanReduce(operation: (acc: Boolean, Boolean) -> Boolean): List { + return runningReduce(operation) +} + +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun CharArray.scanReduce(operation: (acc: Char, Char) -> Char): List { + return runningReduce(operation) +} + +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public inline fun Array.scanReduceIndexed(operation: (index: Int, acc: S, T) -> S): List { + return runningReduceIndexed(operation) +} + +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun ByteArray.scanReduceIndexed(operation: (index: Int, acc: Byte, Byte) -> Byte): List { + return runningReduceIndexed(operation) +} + +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun ShortArray.scanReduceIndexed(operation: (index: Int, acc: Short, Short) -> Short): List { + return runningReduceIndexed(operation) +} + +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun IntArray.scanReduceIndexed(operation: (index: Int, acc: Int, Int) -> Int): List { + return runningReduceIndexed(operation) +} + +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun LongArray.scanReduceIndexed(operation: (index: Int, acc: Long, Long) -> Long): List { + return runningReduceIndexed(operation) +} + +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun FloatArray.scanReduceIndexed(operation: (index: Int, acc: Float, Float) -> Float): List { + return runningReduceIndexed(operation) +} + +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun DoubleArray.scanReduceIndexed(operation: (index: Int, acc: Double, Double) -> Double): List { + return runningReduceIndexed(operation) +} + +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun BooleanArray.scanReduceIndexed(operation: (index: Int, acc: Boolean, Boolean) -> Boolean): List { + return runningReduceIndexed(operation) +} + +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@kotlin.internal.InlineOnly +public inline fun CharArray.scanReduceIndexed(operation: (index: Int, acc: Char, Char) -> Char): List { + return runningReduceIndexed(operation) +} + /** * Returns the sum of all values produced by [selector] function applied to each element in the array. */ diff --git a/libraries/stdlib/common/src/generated/_Collections.kt b/libraries/stdlib/common/src/generated/_Collections.kt index f17f249987c..6b57ccf6e1c 100644 --- a/libraries/stdlib/common/src/generated/_Collections.kt +++ b/libraries/stdlib/common/src/generated/_Collections.kt @@ -2046,11 +2046,10 @@ public inline fun List.reduceRightOrNull(operation: (T, acc: S) -> * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi -public inline fun Iterable.scan(initial: R, operation: (acc: R, T) -> R): List { +@SinceKotlin("1.4") +public inline fun Iterable.runningFold(initial: R, operation: (acc: R, T) -> R): List { val estimatedSize = collectionSizeOrDefault(9) if (estimatedSize == 0) return listOf(initial) val result = ArrayList(estimatedSize + 1).apply { add(initial) } @@ -2072,11 +2071,10 @@ public inline fun Iterable.scan(initial: R, operation: (acc: R, T) -> * @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.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi -public inline fun Iterable.scanIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): List { +@SinceKotlin("1.4") +public inline fun Iterable.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): List { val estimatedSize = collectionSizeOrDefault(9) if (estimatedSize == 0) return listOf(initial) val result = ArrayList(estimatedSize + 1).apply { add(initial) } @@ -2098,11 +2096,11 @@ public inline fun Iterable.scanIndexed(initial: R, operation: (index: * * @param [operation] function that takes current accumulator value and the element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ @SinceKotlin("1.3") @ExperimentalStdlibApi -public inline fun Iterable.scanReduce(operation: (acc: S, T) -> S): List { +public inline fun Iterable.runningReduce(operation: (acc: S, T) -> S): List { val iterator = this.iterator() if (!iterator.hasNext()) return emptyList() var accumulator: S = iterator.next() @@ -2124,11 +2122,10 @@ public inline fun Iterable.scanReduce(operation: (acc: S, T) -> S) * @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.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi -public inline fun Iterable.scanReduceIndexed(operation: (index: Int, acc: S, T) -> S): List { +@SinceKotlin("1.4") +public inline fun Iterable.runningReduceIndexed(operation: (index: Int, acc: S, T) -> S): List { val iterator = this.iterator() if (!iterator.hasNext()) return emptyList() var accumulator: S = iterator.next() @@ -2141,6 +2138,55 @@ public inline fun Iterable.scanReduceIndexed(operation: (index: In return result } +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public inline fun Iterable.scan(initial: R, operation: (acc: R, T) -> R): List { + return runningFold(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original collection and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public inline fun Iterable.scanIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): List { + return runningFoldIndexed(initial, operation) +} + +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public inline fun Iterable.scanReduce(operation: (acc: S, T) -> S): List { + return runningReduce(operation) +} + +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public inline fun Iterable.scanReduceIndexed(operation: (index: Int, acc: S, T) -> S): List { + return runningReduceIndexed(operation) +} + /** * Returns the sum of all values produced by [selector] function applied to each element in the collection. */ diff --git a/libraries/stdlib/common/src/generated/_Sequences.kt b/libraries/stdlib/common/src/generated/_Sequences.kt index 2f48c0bf7a1..439819fc978 100644 --- a/libraries/stdlib/common/src/generated/_Sequences.kt +++ b/libraries/stdlib/common/src/generated/_Sequences.kt @@ -1464,15 +1464,14 @@ public inline fun Sequence.reduceOrNull(operation: (acc: S, T) -> * * The operation is _intermediate_ and _stateless_. * - * @sample samples.collections.Collections.Aggregates.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi -public fun Sequence.scan(initial: R, operation: (acc: R, T) -> R): Sequence { +@SinceKotlin("1.4") +public fun Sequence.runningFold(initial: R, operation: (acc: R, T) -> R): Sequence { return sequence { yield(initial) var accumulator = initial - for (element in this@scan) { + for (element in this@runningFold) { accumulator = operation(accumulator, element) yield(accumulator) } @@ -1493,16 +1492,15 @@ public fun Sequence.scan(initial: R, operation: (acc: R, T) -> R): Seq * * The operation is _intermediate_ and _stateless_. * - * @sample samples.collections.Collections.Aggregates.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi -public fun Sequence.scanIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): Sequence { +@SinceKotlin("1.4") +public fun Sequence.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): Sequence { return sequence { yield(initial) var index = 0 var accumulator = initial - for (element in this@scanIndexed) { + for (element in this@runningFoldIndexed) { accumulator = operation(checkIndexOverflow(index++), accumulator, element) yield(accumulator) } @@ -1520,11 +1518,11 @@ public fun Sequence.scanIndexed(initial: R, operation: (index: Int, ac * * The operation is _intermediate_ and _stateless_. * - * @sample samples.collections.Collections.Aggregates.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ @SinceKotlin("1.3") @ExperimentalStdlibApi -public fun Sequence.scanReduce(operation: (acc: S, T) -> S): Sequence { +public fun Sequence.runningReduce(operation: (acc: S, T) -> S): Sequence { return sequence { val iterator = iterator() if (iterator.hasNext()) { @@ -1550,11 +1548,10 @@ public fun Sequence.scanReduce(operation: (acc: S, T) -> S): Seque * * The operation is _intermediate_ and _stateless_. * - * @sample samples.collections.Collections.Aggregates.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi -public fun Sequence.scanReduceIndexed(operation: (index: Int, acc: S, T) -> S): Sequence { +@SinceKotlin("1.4") +public fun Sequence.runningReduceIndexed(operation: (index: Int, acc: S, T) -> S): Sequence { return sequence { val iterator = iterator() if (iterator.hasNext()) { @@ -1569,6 +1566,63 @@ public fun Sequence.scanReduceIndexed(operation: (index: Int, acc: } } +/** + * Returns a sequence containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting sequence. + * The [initial] value should also be immutable (or should not be mutated) + * as it may be passed to [operation] function later because of sequence's lazy nature. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * The operation is _intermediate_ and _stateless_. + * + * @sample samples.collections.Collections.Aggregates.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun Sequence.scan(initial: R, operation: (acc: R, T) -> R): Sequence { + return runningFold(initial, operation) +} + +/** + * Returns a sequence containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original sequence and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting sequence. + * The [initial] value should also be immutable (or should not be mutated) + * as it may be passed to [operation] function later because of sequence's lazy nature. + * + * @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 _intermediate_ and _stateless_. + * + * @sample samples.collections.Collections.Aggregates.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun Sequence.scanIndexed(initial: R, operation: (index: Int, acc: R, T) -> R): Sequence { + return runningFoldIndexed(initial, operation) +} + +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun Sequence.scanReduce(operation: (acc: S, T) -> S): Sequence { + return runningReduce(operation) +} + +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public fun Sequence.scanReduceIndexed(operation: (index: Int, acc: S, T) -> S): Sequence { + return runningReduceIndexed(operation) +} + /** * Returns the sum of all values produced by [selector] function applied to each element in the sequence. * diff --git a/libraries/stdlib/common/src/generated/_Strings.kt b/libraries/stdlib/common/src/generated/_Strings.kt index 7f01993a1f8..ad59489c882 100644 --- a/libraries/stdlib/common/src/generated/_Strings.kt +++ b/libraries/stdlib/common/src/generated/_Strings.kt @@ -1357,11 +1357,10 @@ public inline fun CharSequence.reduceRightOrNull(operation: (Char, acc: Char) -> * * @param [operation] function that takes current accumulator value and a character, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi -public inline fun CharSequence.scan(initial: R, operation: (acc: R, Char) -> R): List { +@SinceKotlin("1.4") +public inline fun CharSequence.runningFold(initial: R, operation: (acc: R, Char) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(length + 1).apply { add(initial) } var accumulator = initial @@ -1382,11 +1381,10 @@ public inline fun CharSequence.scan(initial: R, operation: (acc: R, Char) -> * @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.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi -public inline fun CharSequence.scanIndexed(initial: R, operation: (index: Int, acc: R, Char) -> R): List { +@SinceKotlin("1.4") +public inline fun CharSequence.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, Char) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(length + 1).apply { add(initial) } var accumulator = initial @@ -1406,11 +1404,10 @@ public inline fun CharSequence.scanIndexed(initial: R, operation: (index: In * * @param [operation] function that takes current accumulator value and a character, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi -public inline fun CharSequence.scanReduce(operation: (acc: Char, Char) -> Char): List { +@SinceKotlin("1.4") +public inline fun CharSequence.runningReduce(operation: (acc: Char, Char) -> Char): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(length).apply { add(accumulator) } @@ -1431,11 +1428,10 @@ public inline fun CharSequence.scanReduce(operation: (acc: Char, Char) -> Char): * @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.scanReduce + * @sample samples.collections.Collections.Aggregates.runningReduce */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi -public inline fun CharSequence.scanReduceIndexed(operation: (index: Int, acc: Char, Char) -> Char): List { +@SinceKotlin("1.4") +public inline fun CharSequence.runningReduceIndexed(operation: (index: Int, acc: Char, Char) -> Char): List { if (isEmpty()) return emptyList() var accumulator = this[0] val result = ArrayList(length).apply { add(accumulator) } @@ -1446,6 +1442,55 @@ public inline fun CharSequence.scanReduceIndexed(operation: (index: Int, acc: Ch return result } +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each character and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and a character, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public inline fun CharSequence.scan(initial: R, operation: (acc: R, Char) -> R): List { + return runningFold(initial, operation) +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each character, its index in the original char sequence and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public inline fun CharSequence.scanIndexed(initial: R, operation: (index: Int, acc: R, Char) -> R): List { + return runningFoldIndexed(initial, operation) +} + +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public inline fun CharSequence.scanReduce(operation: (acc: Char, Char) -> Char): List { + return runningReduce(operation) +} + +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) +@SinceKotlin("1.3") +@ExperimentalStdlibApi +public inline fun CharSequence.scanReduceIndexed(operation: (index: Int, acc: Char, Char) -> Char): List { + return runningReduceIndexed(operation) +} + /** * Returns the sum of all values produced by [selector] function applied to each character in the char sequence. */ diff --git a/libraries/stdlib/common/src/generated/_UArrays.kt b/libraries/stdlib/common/src/generated/_UArrays.kt index f46db1b3ca4..8056fa1d662 100644 --- a/libraries/stdlib/common/src/generated/_UArrays.kt +++ b/libraries/stdlib/common/src/generated/_UArrays.kt @@ -6719,13 +6719,12 @@ public inline fun UShortArray.reduceRightOrNull(operation: (UShort, acc: UShort) * * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. * - * @sample samples.collections.Collections.Aggregates.scan + * @sample samples.collections.Collections.Aggregates.runningFold */ -@SinceKotlin("1.3") -@ExperimentalStdlibApi +@SinceKotlin("1.4") @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly -public inline fun UIntArray.scan(initial: R, operation: (acc: R, UInt) -> R): List { +public inline fun UIntArray.runningFold(initial: R, operation: (acc: R, UInt) -> R): List { if (isEmpty()) return listOf(initial) val result = ArrayList(size + 1).apply { add(initial) } var accumulator = initial @@ -6736,6 +6735,408 @@ public inline fun UIntArray.scan(initial: R, operation: (acc: R, UInt) -> R) return result } +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.runningFold + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.runningFold(initial: R, operation: (acc: R, ULong) -> R): List { + if (isEmpty()) return listOf(initial) + val result = ArrayList(size + 1).apply { add(initial) } + var accumulator = initial + for (element in this) { + accumulator = operation(accumulator, element) + result.add(accumulator) + } + return result +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.runningFold + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.runningFold(initial: R, operation: (acc: R, UByte) -> R): List { + if (isEmpty()) return listOf(initial) + val result = ArrayList(size + 1).apply { add(initial) } + var accumulator = initial + for (element in this) { + accumulator = operation(accumulator, element) + result.add(accumulator) + } + return result +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.runningFold + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.runningFold(initial: R, operation: (acc: R, UShort) -> R): List { + if (isEmpty()) return listOf(initial) + val result = ArrayList(size + 1).apply { add(initial) } + var accumulator = initial + for (element in this) { + accumulator = operation(accumulator, element) + result.add(accumulator) + } + return result +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.runningFold + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, UInt) -> R): List { + if (isEmpty()) return listOf(initial) + val result = ArrayList(size + 1).apply { add(initial) } + var accumulator = initial + for (index in indices) { + accumulator = operation(index, accumulator, this[index]) + result.add(accumulator) + } + return result +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.runningFold + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, ULong) -> R): List { + if (isEmpty()) return listOf(initial) + val result = ArrayList(size + 1).apply { add(initial) } + var accumulator = initial + for (index in indices) { + accumulator = operation(index, accumulator, this[index]) + result.add(accumulator) + } + return result +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.runningFold + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, UByte) -> R): List { + if (isEmpty()) return listOf(initial) + val result = ArrayList(size + 1).apply { add(initial) } + var accumulator = initial + for (index in indices) { + accumulator = operation(index, accumulator, this[index]) + result.add(accumulator) + } + return result +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.runningFold + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.runningFoldIndexed(initial: R, operation: (index: Int, acc: R, UShort) -> R): List { + if (isEmpty()) return listOf(initial) + val result = ArrayList(size + 1).apply { add(initial) } + var accumulator = initial + for (index in indices) { + accumulator = operation(index, accumulator, this[index]) + result.add(accumulator) + } + return result +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with the first element of this array. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.runningReduce + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.runningReduce(operation: (acc: UInt, UInt) -> UInt): List { + if (isEmpty()) return emptyList() + var accumulator = this[0] + val result = ArrayList(size).apply { add(accumulator) } + for (index in 1 until size) { + accumulator = operation(accumulator, this[index]) + result.add(accumulator) + } + return result +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with the first element of this array. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.runningReduce + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.runningReduce(operation: (acc: ULong, ULong) -> ULong): List { + if (isEmpty()) return emptyList() + var accumulator = this[0] + val result = ArrayList(size).apply { add(accumulator) } + for (index in 1 until size) { + accumulator = operation(accumulator, this[index]) + result.add(accumulator) + } + return result +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with the first element of this array. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.runningReduce + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.runningReduce(operation: (acc: UByte, UByte) -> UByte): List { + if (isEmpty()) return emptyList() + var accumulator = this[0] + val result = ArrayList(size).apply { add(accumulator) } + for (index in 1 until size) { + accumulator = operation(accumulator, this[index]) + result.add(accumulator) + } + return result +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with the first element of this array. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.runningReduce + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.runningReduce(operation: (acc: UShort, UShort) -> UShort): List { + if (isEmpty()) return emptyList() + var accumulator = this[0] + val result = ArrayList(size).apply { add(accumulator) } + for (index in 1 until size) { + accumulator = operation(accumulator, this[index]) + result.add(accumulator) + } + return result +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with the first element of this array. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.runningReduce + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.runningReduceIndexed(operation: (index: Int, acc: UInt, UInt) -> UInt): List { + if (isEmpty()) return emptyList() + var accumulator = this[0] + val result = ArrayList(size).apply { add(accumulator) } + for (index in 1 until size) { + accumulator = operation(index, accumulator, this[index]) + result.add(accumulator) + } + return result +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with the first element of this array. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.runningReduce + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun ULongArray.runningReduceIndexed(operation: (index: Int, acc: ULong, ULong) -> ULong): List { + if (isEmpty()) return emptyList() + var accumulator = this[0] + val result = ArrayList(size).apply { add(accumulator) } + for (index in 1 until size) { + accumulator = operation(index, accumulator, this[index]) + result.add(accumulator) + } + return result +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with the first element of this array. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.runningReduce + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UByteArray.runningReduceIndexed(operation: (index: Int, acc: UByte, UByte) -> UByte): List { + if (isEmpty()) return emptyList() + var accumulator = this[0] + val result = ArrayList(size).apply { add(accumulator) } + for (index in 1 until size) { + accumulator = operation(index, accumulator, this[index]) + result.add(accumulator) + } + return result +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element, its index in the original array and current accumulator value that starts with the first element of this array. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @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.runningReduce + */ +@SinceKotlin("1.4") +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UShortArray.runningReduceIndexed(operation: (index: Int, acc: UShort, UShort) -> UShort): List { + if (isEmpty()) return emptyList() + var accumulator = this[0] + val result = ArrayList(size).apply { add(accumulator) } + for (index in 1 until size) { + accumulator = operation(index, accumulator, this[index]) + result.add(accumulator) + } + return result +} + +/** + * Returns a list containing successive accumulation values generated by applying [operation] from left to right + * to each element and current accumulator value that starts with [initial] value. + * + * Note that `acc` value passed to [operation] function should not be mutated; + * otherwise it would affect the previous value in resulting list. + * + * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. + * + * @sample samples.collections.Collections.Aggregates.scan + */ +@SinceKotlin("1.3") +@ExperimentalStdlibApi +@ExperimentalUnsignedTypes +@kotlin.internal.InlineOnly +public inline fun UIntArray.scan(initial: R, operation: (acc: R, UInt) -> R): List { + return runningFold(initial, operation) +} + /** * Returns a list containing successive accumulation values generated by applying [operation] from left to right * to each element and current accumulator value that starts with [initial] value. @@ -6752,14 +7153,7 @@ public inline fun UIntArray.scan(initial: R, operation: (acc: R, UInt) -> R) @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public inline fun ULongArray.scan(initial: R, operation: (acc: R, ULong) -> R): List { - if (isEmpty()) return listOf(initial) - val result = ArrayList(size + 1).apply { add(initial) } - var accumulator = initial - for (element in this) { - accumulator = operation(accumulator, element) - result.add(accumulator) - } - return result + return runningFold(initial, operation) } /** @@ -6778,14 +7172,7 @@ public inline fun ULongArray.scan(initial: R, operation: (acc: R, ULong) -> @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public inline fun UByteArray.scan(initial: R, operation: (acc: R, UByte) -> R): List { - if (isEmpty()) return listOf(initial) - val result = ArrayList(size + 1).apply { add(initial) } - var accumulator = initial - for (element in this) { - accumulator = operation(accumulator, element) - result.add(accumulator) - } - return result + return runningFold(initial, operation) } /** @@ -6804,14 +7191,7 @@ public inline fun UByteArray.scan(initial: R, operation: (acc: R, UByte) -> @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public inline fun UShortArray.scan(initial: R, operation: (acc: R, UShort) -> R): List { - if (isEmpty()) return listOf(initial) - val result = ArrayList(size + 1).apply { add(initial) } - var accumulator = initial - for (element in this) { - accumulator = operation(accumulator, element) - result.add(accumulator) - } - return result + return runningFold(initial, operation) } /** @@ -6831,14 +7211,7 @@ public inline fun UShortArray.scan(initial: R, operation: (acc: R, UShort) - @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public inline fun UIntArray.scanIndexed(initial: R, operation: (index: Int, acc: R, UInt) -> R): List { - if (isEmpty()) return listOf(initial) - val result = ArrayList(size + 1).apply { add(initial) } - var accumulator = initial - for (index in indices) { - accumulator = operation(index, accumulator, this[index]) - result.add(accumulator) - } - return result + return runningFoldIndexed(initial, operation) } /** @@ -6858,14 +7231,7 @@ public inline fun UIntArray.scanIndexed(initial: R, operation: (index: Int, @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public inline fun ULongArray.scanIndexed(initial: R, operation: (index: Int, acc: R, ULong) -> R): List { - if (isEmpty()) return listOf(initial) - val result = ArrayList(size + 1).apply { add(initial) } - var accumulator = initial - for (index in indices) { - accumulator = operation(index, accumulator, this[index]) - result.add(accumulator) - } - return result + return runningFoldIndexed(initial, operation) } /** @@ -6885,14 +7251,7 @@ public inline fun ULongArray.scanIndexed(initial: R, operation: (index: Int, @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public inline fun UByteArray.scanIndexed(initial: R, operation: (index: Int, acc: R, UByte) -> R): List { - if (isEmpty()) return listOf(initial) - val result = ArrayList(size + 1).apply { add(initial) } - var accumulator = initial - for (index in indices) { - accumulator = operation(index, accumulator, this[index]) - result.add(accumulator) - } - return result + return runningFoldIndexed(initial, operation) } /** @@ -6912,226 +7271,79 @@ public inline fun UByteArray.scanIndexed(initial: R, operation: (index: Int, @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public inline fun UShortArray.scanIndexed(initial: R, operation: (index: Int, acc: R, UShort) -> R): List { - if (isEmpty()) return listOf(initial) - val result = ArrayList(size + 1).apply { add(initial) } - var accumulator = initial - for (index in indices) { - accumulator = operation(index, accumulator, this[index]) - result.add(accumulator) - } - return result + return runningFoldIndexed(initial, operation) } -/** - * Returns a list containing successive accumulation values generated by applying [operation] from left to right - * to each element and current accumulator value that starts with the first element of this array. - * - * Note that `acc` value passed to [operation] function should not be mutated; - * otherwise it would affect the previous value in resulting list. - * - * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. - * - * @sample samples.collections.Collections.Aggregates.scanReduce - */ +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) @SinceKotlin("1.3") @ExperimentalStdlibApi @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public inline fun UIntArray.scanReduce(operation: (acc: UInt, UInt) -> UInt): List { - if (isEmpty()) return emptyList() - var accumulator = this[0] - val result = ArrayList(size).apply { add(accumulator) } - for (index in 1 until size) { - accumulator = operation(accumulator, this[index]) - result.add(accumulator) - } - return result + return runningReduce(operation) } -/** - * Returns a list containing successive accumulation values generated by applying [operation] from left to right - * to each element and current accumulator value that starts with the first element of this array. - * - * Note that `acc` value passed to [operation] function should not be mutated; - * otherwise it would affect the previous value in resulting list. - * - * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. - * - * @sample samples.collections.Collections.Aggregates.scanReduce - */ +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) @SinceKotlin("1.3") @ExperimentalStdlibApi @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public inline fun ULongArray.scanReduce(operation: (acc: ULong, ULong) -> ULong): List { - if (isEmpty()) return emptyList() - var accumulator = this[0] - val result = ArrayList(size).apply { add(accumulator) } - for (index in 1 until size) { - accumulator = operation(accumulator, this[index]) - result.add(accumulator) - } - return result + return runningReduce(operation) } -/** - * Returns a list containing successive accumulation values generated by applying [operation] from left to right - * to each element and current accumulator value that starts with the first element of this array. - * - * Note that `acc` value passed to [operation] function should not be mutated; - * otherwise it would affect the previous value in resulting list. - * - * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. - * - * @sample samples.collections.Collections.Aggregates.scanReduce - */ +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) @SinceKotlin("1.3") @ExperimentalStdlibApi @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public inline fun UByteArray.scanReduce(operation: (acc: UByte, UByte) -> UByte): List { - if (isEmpty()) return emptyList() - var accumulator = this[0] - val result = ArrayList(size).apply { add(accumulator) } - for (index in 1 until size) { - accumulator = operation(accumulator, this[index]) - result.add(accumulator) - } - return result + return runningReduce(operation) } -/** - * Returns a list containing successive accumulation values generated by applying [operation] from left to right - * to each element and current accumulator value that starts with the first element of this array. - * - * Note that `acc` value passed to [operation] function should not be mutated; - * otherwise it would affect the previous value in resulting list. - * - * @param [operation] function that takes current accumulator value and an element, and calculates the next accumulator value. - * - * @sample samples.collections.Collections.Aggregates.scanReduce - */ +@Deprecated("Use runningReduce instead.", ReplaceWith("runningReduce(operation)")) @SinceKotlin("1.3") @ExperimentalStdlibApi @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public inline fun UShortArray.scanReduce(operation: (acc: UShort, UShort) -> UShort): List { - if (isEmpty()) return emptyList() - var accumulator = this[0] - val result = ArrayList(size).apply { add(accumulator) } - for (index in 1 until size) { - accumulator = operation(accumulator, this[index]) - result.add(accumulator) - } - return result + return runningReduce(operation) } -/** - * Returns a list containing successive accumulation values generated by applying [operation] from left to right - * to each element, its index in the original array and current accumulator value that starts with the first element of this array. - * - * Note that `acc` value passed to [operation] function should not be mutated; - * otherwise it would affect the previous value in resulting list. - * - * @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.scanReduce - */ +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) @SinceKotlin("1.3") @ExperimentalStdlibApi @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public inline fun UIntArray.scanReduceIndexed(operation: (index: Int, acc: UInt, UInt) -> UInt): List { - if (isEmpty()) return emptyList() - var accumulator = this[0] - val result = ArrayList(size).apply { add(accumulator) } - for (index in 1 until size) { - accumulator = operation(index, accumulator, this[index]) - result.add(accumulator) - } - return result + return runningReduceIndexed(operation) } -/** - * Returns a list containing successive accumulation values generated by applying [operation] from left to right - * to each element, its index in the original array and current accumulator value that starts with the first element of this array. - * - * Note that `acc` value passed to [operation] function should not be mutated; - * otherwise it would affect the previous value in resulting list. - * - * @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.scanReduce - */ +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) @SinceKotlin("1.3") @ExperimentalStdlibApi @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public inline fun ULongArray.scanReduceIndexed(operation: (index: Int, acc: ULong, ULong) -> ULong): List { - if (isEmpty()) return emptyList() - var accumulator = this[0] - val result = ArrayList(size).apply { add(accumulator) } - for (index in 1 until size) { - accumulator = operation(index, accumulator, this[index]) - result.add(accumulator) - } - return result + return runningReduceIndexed(operation) } -/** - * Returns a list containing successive accumulation values generated by applying [operation] from left to right - * to each element, its index in the original array and current accumulator value that starts with the first element of this array. - * - * Note that `acc` value passed to [operation] function should not be mutated; - * otherwise it would affect the previous value in resulting list. - * - * @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.scanReduce - */ +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) @SinceKotlin("1.3") @ExperimentalStdlibApi @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public inline fun UByteArray.scanReduceIndexed(operation: (index: Int, acc: UByte, UByte) -> UByte): List { - if (isEmpty()) return emptyList() - var accumulator = this[0] - val result = ArrayList(size).apply { add(accumulator) } - for (index in 1 until size) { - accumulator = operation(index, accumulator, this[index]) - result.add(accumulator) - } - return result + return runningReduceIndexed(operation) } -/** - * Returns a list containing successive accumulation values generated by applying [operation] from left to right - * to each element, its index in the original array and current accumulator value that starts with the first element of this array. - * - * Note that `acc` value passed to [operation] function should not be mutated; - * otherwise it would affect the previous value in resulting list. - * - * @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.scanReduce - */ +@Deprecated("Use runningReduceIndexed instead.", ReplaceWith("runningReduceIndexed(operation)")) @SinceKotlin("1.3") @ExperimentalStdlibApi @ExperimentalUnsignedTypes @kotlin.internal.InlineOnly public inline fun UShortArray.scanReduceIndexed(operation: (index: Int, acc: UShort, UShort) -> UShort): List { - if (isEmpty()) return emptyList() - var accumulator = this[0] - val result = ArrayList(size).apply { add(accumulator) } - for (index in 1 until size) { - accumulator = operation(index, accumulator, this[index]) - result.add(accumulator) - } - return result + return runningReduceIndexed(operation) } /** diff --git a/libraries/stdlib/samples/test/samples/collections/collections.kt b/libraries/stdlib/samples/test/samples/collections/collections.kt index 3c87c74bfb0..9b33e17732f 100644 --- a/libraries/stdlib/samples/test/samples/collections/collections.kt +++ b/libraries/stdlib/samples/test/samples/collections/collections.kt @@ -722,12 +722,21 @@ class Collections { } @Sample - fun scanReduce() { + fun runningFold() { val strings = listOf("a", "b", "c", "d") - assertPrints(strings.scanReduce { acc, string -> acc + string }, "[a, ab, abc, abcd]") - assertPrints(strings.scanReduceIndexed { index, acc, string -> acc + string + index }, "[a, ab1, ab1c2, ab1c2d3]") + assertPrints(strings.runningFold("s") { acc, string -> acc + string }, "[s, sa, sab, sabc, sabcd]") + assertPrints(strings.runningFoldIndexed("s") { index, acc, string -> acc + string + index }, "[s, sa0, sa0b1, sa0b1c2, sa0b1c2d3]") - assertPrints(emptyList().scanReduce { _, _ -> "X" }, "[]") + assertPrints(emptyList().runningFold("s") { _, _ -> "X" }, "[s]") + } + + @Sample + fun runningReduce() { + val strings = listOf("a", "b", "c", "d") + assertPrints(strings.runningReduce { acc, string -> acc + string }, "[a, ab, abc, abcd]") + assertPrints(strings.runningReduceIndexed { index, acc, string -> acc + string + index }, "[a, ab1, ab1c2, ab1c2d3]") + + assertPrints(emptyList().runningReduce { _, _ -> "X" }, "[]") } } diff --git a/libraries/stdlib/test/collections/ArraysTest.kt b/libraries/stdlib/test/collections/ArraysTest.kt index 51450c75faf..be2d9aac933 100644 --- a/libraries/stdlib/test/collections/ArraysTest.kt +++ b/libraries/stdlib/test/collections/ArraysTest.kt @@ -1141,6 +1141,27 @@ class ArraysTest { } } + @Test + fun runningFold() { + for (size in 0 until 4) { + val expected = listOf("", "0", "01", "012", "0123").take(size + 1) + // Array + assertEquals(expected, Array(size) { it }.runningFold("") { acc, e -> acc + e }) + // Primitive Arrays + assertEquals(expected, ByteArray(size) { it.toByte() }.runningFold("") { acc, e -> acc + e }) + assertEquals(expected, CharArray(size) { '0' + it }.runningFold("") { acc, e -> acc + e }) + assertEquals(expected, ShortArray(size) { it.toShort() }.runningFold("") { acc, e -> acc + e }) + assertEquals(expected, IntArray(size) { it }.runningFold("") { acc, e -> acc + e }) + assertEquals(expected, LongArray(size) { it.toLong() }.runningFold("") { acc, e -> acc + e }) + assertEquals(expected, FloatArray(size) { it.toFloat() }.runningFold("") { acc, e -> acc + e.toInt() }) + assertEquals(expected, DoubleArray(size) { it.toDouble() }.runningFold("") { acc, e -> acc + e.toInt() }) + assertEquals( + expected.map { it.map { c -> c.toInt() % 2 == 0 }.joinToString(separator = "") }, + BooleanArray(size) { it % 2 == 0 }.runningFold("") { acc, e -> acc + e } + ) + } + } + @Test fun scanIndexed() { for (size in 0 until 4) { @@ -1185,92 +1206,137 @@ class ArraysTest { ) } } - + @Test - fun scanReduce() { + fun runningFoldIndexed() { for (size in 0 until 4) { - val expected = listOf(0, 1, 3, 6).take(size) + val expected = listOf("+", "+[0: a]", "+[0: a][1: b]", "+[0: a][1: b][2: c]", "+[0: a][1: b][2: c][3: d]").take(size + 1) // Array assertEquals( expected, - Array(size) { it }.scanReduce { acc, e -> acc + e } + Array(size) { 'a' + it }.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: $e]" } ) // Primitive Arrays assertEquals( - expected.map { it.toByte() }, - ByteArray(size) { it.toByte() }.scanReduce { acc, e -> (acc + e).toByte() } - ) - assertEquals( - expected.map { it.toChar() }, - CharArray(size) { it.toChar() }.scanReduce { acc, e -> acc + e.toInt() } - ) - assertEquals( - expected.map { it.toShort() }, - ShortArray(size) { it.toShort() }.scanReduce { acc, e -> (acc + e).toShort() } + expected, + ByteArray(size) { it.toByte() }.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: ${'a' + e.toInt()}]" } ) assertEquals( expected, - IntArray(size) { it }.scanReduce { acc, e -> acc + e } + CharArray(size) { it.toChar() }.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: ${'a' + e.toInt()}]" } ) assertEquals( - expected.map { it.toLong() }, - LongArray(size) { it.toLong() }.scanReduce { acc, e -> acc + e } + expected, + ShortArray(size) { it.toShort() }.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: ${'a' + e.toInt()}]" } ) assertEquals( - expected.map { it.toFloat() }, - FloatArray(size) { it.toFloat() }.scanReduce { acc, e -> acc + e.toInt() } + expected, + IntArray(size) { it }.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: ${'a' + e}]" } ) assertEquals( - expected.map { it.toDouble() }, - DoubleArray(size) { it.toDouble() }.scanReduce { acc, e -> acc + e.toInt() } + expected, + LongArray(size) { it.toLong() }.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: ${'a' + e.toInt()}]" } ) assertEquals( - expected.indices.map { it % 2 == 0 }, - BooleanArray(size) { true }.scanReduce { acc, e -> acc != e } + expected, + FloatArray(size) { it.toFloat() }.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: ${'a' + e.toInt()}]" } + ) + assertEquals( + expected, + DoubleArray(size) { it.toDouble() }.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: ${'a' + e.toInt()}]" } + ) + assertEquals( + expected.map { it.map { c -> if (c.isAsciiLetter()) c.toInt() % 2 != 0 else c }.joinToString(separator = "") }, + BooleanArray(size) { it % 2 == 0 }.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: $e]" } ) } } @Test - fun scanReduceIndexed() { + fun runningReduce() { + for (size in 0 until 4) { + val expected = listOf(0, 1, 3, 6).take(size) + // Array + assertEquals( + expected, + Array(size) { it }.runningReduce { acc, e -> acc + e } + ) + // Primitive Arrays + assertEquals( + expected.map { it.toByte() }, + ByteArray(size) { it.toByte() }.runningReduce { acc, e -> (acc + e).toByte() } + ) + assertEquals( + expected.map { it.toChar() }, + CharArray(size) { it.toChar() }.runningReduce { acc, e -> acc + e.toInt() } + ) + assertEquals( + expected.map { it.toShort() }, + ShortArray(size) { it.toShort() }.runningReduce { acc, e -> (acc + e).toShort() } + ) + assertEquals( + expected, + IntArray(size) { it }.runningReduce { acc, e -> acc + e } + ) + assertEquals( + expected.map { it.toLong() }, + LongArray(size) { it.toLong() }.runningReduce { acc, e -> acc + e } + ) + assertEquals( + expected.map { it.toFloat() }, + FloatArray(size) { it.toFloat() }.runningReduce { acc, e -> acc + e.toInt() } + ) + assertEquals( + expected.map { it.toDouble() }, + DoubleArray(size) { it.toDouble() }.runningReduce { acc, e -> acc + e.toInt() } + ) + assertEquals( + expected.indices.map { it % 2 == 0 }, + BooleanArray(size) { true }.runningReduce { acc, e -> acc != e } + ) + } + } + + @Test + fun runningReduceIndexed() { for (size in 0 until 4) { val expected = listOf(0, 1, 6, 27).take(size) // Array assertEquals( expected, - Array(size) { it }.scanReduceIndexed { index, acc, e -> index * (acc + e) } + Array(size) { it }.runningReduceIndexed { index, acc, e -> index * (acc + e) } ) // Primitive Arrays assertEquals( expected.map { it.toByte() }, - ByteArray(size) { it.toByte() }.scanReduceIndexed { index, acc, e -> (index * (acc + e)).toByte() }) + ByteArray(size) { it.toByte() }.runningReduceIndexed { index, acc, e -> (index * (acc + e)).toByte() }) assertEquals( expected.map { it.toChar() }, - CharArray(size) { it.toChar() }.scanReduceIndexed { index, acc, e -> (index * (acc.toInt() + e.toInt())).toChar() } + CharArray(size) { it.toChar() }.runningReduceIndexed { index, acc, e -> (index * (acc.toInt() + e.toInt())).toChar() } ) assertEquals( expected.map { it.toShort() }, - ShortArray(size) { it.toShort() }.scanReduceIndexed { index, acc, e -> (index * (acc + e)).toShort() } + ShortArray(size) { it.toShort() }.runningReduceIndexed { index, acc, e -> (index * (acc + e)).toShort() } ) assertEquals( expected, - IntArray(size) { it }.scanReduceIndexed { index, acc, e -> index * (acc + e) } + IntArray(size) { it }.runningReduceIndexed { index, acc, e -> index * (acc + e) } ) assertEquals( expected.map { it.toLong() }, - LongArray(size) { it.toLong() }.scanReduceIndexed { index, acc, e -> index * (acc + e) } + LongArray(size) { it.toLong() }.runningReduceIndexed { index, acc, e -> index * (acc + e) } ) assertEquals( expected.map { it.toFloat() }, - FloatArray(size) { it.toFloat() }.scanReduceIndexed { index, acc, e -> index * (acc + e) } + FloatArray(size) { it.toFloat() }.runningReduceIndexed { index, acc, e -> index * (acc + e) } ) assertEquals( expected.map { it.toDouble() }, - DoubleArray(size) { it.toDouble() }.scanReduceIndexed { index, acc, e -> index * (acc + e) } + DoubleArray(size) { it.toDouble() }.runningReduceIndexed { index, acc, e -> index * (acc + e) } ) assertEquals( expected.indices.map { it % 2 == 0 }, - BooleanArray(size) { true }.scanReduceIndexed { index, acc, e -> acc != e && index % 2 == 0 } + BooleanArray(size) { true }.runningReduceIndexed { index, acc, e -> acc != e && index % 2 == 0 } ) } } diff --git a/libraries/stdlib/test/collections/CollectionTest.kt b/libraries/stdlib/test/collections/CollectionTest.kt index d19f6635a25..74cf9ff3ba5 100644 --- a/libraries/stdlib/test/collections/CollectionTest.kt +++ b/libraries/stdlib/test/collections/CollectionTest.kt @@ -397,6 +397,7 @@ class CollectionTest { for (size in 0 until 4) { val expected = listOf("", "0", "01", "012", "0123").take(size + 1) assertEquals(expected, List(size) { it }.scan("") { acc, e -> acc + e }) + assertEquals(expected, List(size) { it }.runningFold("") { acc, e -> acc + e }) } } @@ -405,22 +406,23 @@ class CollectionTest { for (size in 0 until 4) { val expected = listOf("+", "+[0: a]", "+[0: a][1: b]", "+[0: a][1: b][2: c]", "+[0: a][1: b][2: c][3: d]").take(size + 1) assertEquals(expected, List(size) { 'a' + it }.scanIndexed("+") { index, acc, e -> "$acc[$index: $e]" }) + assertEquals(expected, List(size) { 'a' + it }.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: $e]" }) } } @Test - fun scanReduce() { + fun runningReduce() { for (size in 0 until 4) { val expected = listOf(0, 1, 3, 6).take(size) - assertEquals(expected, List(size) { it }.scanReduce { acc, e -> acc + e }) + assertEquals(expected, List(size) { it }.runningReduce { acc, e -> acc + e }) } } @Test - fun scanReduceIndexed() { + fun runningReduceIndexed() { for (size in 0 until 4) { val expected = listOf(0, 1, 6, 27).take(size) - assertEquals(expected, List(size) { it }.scanReduceIndexed { index, acc, e -> index * (acc + e) }) + assertEquals(expected, List(size) { it }.runningReduceIndexed { index, acc, e -> index * (acc + e) }) } } diff --git a/libraries/stdlib/test/collections/SequenceTest.kt b/libraries/stdlib/test/collections/SequenceTest.kt index 824a92386d7..53e13ed9c78 100644 --- a/libraries/stdlib/test/collections/SequenceTest.kt +++ b/libraries/stdlib/test/collections/SequenceTest.kt @@ -166,41 +166,35 @@ public class SequenceTest { @Test fun scan() { for (size in 0 until 4) { - assertEquals( - sequenceOf("", "0", "01", "012").take(size).toList(), - indexSequence().scan("") { acc, e -> acc + e }.take(size).toList() - ) + val expected = listOf("_", "_0", "_01", "_012").take(size) + assertEquals(expected, indexSequence().scan("_") { acc, e -> acc + e }.take(size).toList()) + assertEquals(expected, indexSequence().runningFold("_") { acc, e -> acc + e }.take(size).toList()) } } @Test fun scanIndexed() { for (size in 0 until 4) { - assertEquals( - sequenceOf("+", "+[0: a]", "+[0: a][1: b]", "+[0: a][1: b][2: c]").take(size).toList(), - indexSequence().map { 'a' + it }.scanIndexed("+") { index, acc, e -> "$acc[$index: $e]" }.take(size).toList() - ) + val source = indexSequence().map { 'a' + it } + val expected = listOf("+", "+[0: a]", "+[0: a][1: b]", "+[0: a][1: b][2: c]").take(size) + assertEquals(expected, source.scanIndexed("+") { index, acc, e -> "$acc[$index: $e]" }.take(size).toList()) + assertEquals(expected, source.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: $e]" }.take(size).toList()) } } @Test - fun scanReduce() { + fun runningReduce() { for (size in 0 until 4) { val expected = listOf(0, 1, 3, 6).subList(0, size) - assertEquals( - sequenceOf(0, 1, 3, 6).take(size).toList(), - indexSequence().scanReduce { acc, e -> acc + e }.take(size).toList() - ) + assertEquals(expected, indexSequence().runningReduce { acc, e -> acc + e }.take(size).toList()) } } @Test - fun scanReduceIndexed() { + fun runningReduceIndexed() { for (size in 0 until 4) { - assertEquals( - sequenceOf(0, 1, 6, 27).take(size).toList(), - indexSequence().scanReduceIndexed { index, acc, e -> index * (acc + e) }.take(size).toList() - ) + val expected = listOf(0, 1, 6, 27).take(size) + assertEquals(expected, indexSequence().runningReduceIndexed { index, acc, e -> index * (acc + e) }.take(size).toList()) } } diff --git a/libraries/stdlib/test/collections/UnsignedArraysTest.kt b/libraries/stdlib/test/collections/UnsignedArraysTest.kt index 892f904e216..2b30224ab13 100644 --- a/libraries/stdlib/test/collections/UnsignedArraysTest.kt +++ b/libraries/stdlib/test/collections/UnsignedArraysTest.kt @@ -674,6 +674,17 @@ class UnsignedArraysTest { } } + @Test + fun runningFold() { + for (size in 0 until 4) { + val expected = listOf("", "0", "01", "012", "0123").subList(0, size + 1) + assertEquals(expected, UByteArray(size) { it.toUByte() }.runningFold("") { acc, e -> acc + e }) + assertEquals(expected, UShortArray(size) { it.toUShort() }.runningFold("") { acc, e -> acc + e }) + assertEquals(expected, UIntArray(size) { it.toUInt() }.runningFold("") { acc, e -> acc + e }) + assertEquals(expected, ULongArray(size) { it.toULong() }.runningFold("") { acc, e -> acc + e }) + } + } + @Test fun scanIndexed() { for (size in 0 until 4) { @@ -698,47 +709,70 @@ class UnsignedArraysTest { } @Test - fun scanReduce() { + fun runningFoldIndexed() { for (size in 0 until 4) { - val expected = listOf(0, 1, 3, 6).subList(0, size) + val expected = listOf("+", "+[0: a]", "+[0: a][1: b]", "+[0: a][1: b][2: c]", "+[0: a][1: b][2: c][3: d]").subList(0, size + 1) assertEquals( - expected.map { it.toUByte() }, - UByteArray(size) { it.toUByte() }.scanReduce { acc, e -> (acc + e).toUByte() } + expected, + UByteArray(size) { it.toUByte() }.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: ${'a' + e.toInt()}]" } ) assertEquals( - expected.map { it.toUShort() }, - UShortArray(size) { it.toUShort() }.scanReduce { acc, e -> (acc + e).toUShort() } + expected, + UShortArray(size) { it.toUShort() }.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: ${'a' + e.toInt()}]" } ) assertEquals( - expected.map { it.toUInt() }, - UIntArray(size) { it.toUInt() }.scanReduce { acc, e -> acc + e } + expected, + UIntArray(size) { it.toUInt() }.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: ${'a' + e.toInt()}]" } ) assertEquals( - expected.map { it.toULong() }, - ULongArray(size) { it.toULong() }.scanReduce { acc, e -> acc + e } + expected, + ULongArray(size) { it.toULong() }.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: ${'a' + e.toInt()}]" } ) } } @Test - fun scanReduceIndexed() { + fun runningReduce() { + for (size in 0 until 4) { + val expected = listOf(0, 1, 3, 6).subList(0, size) + assertEquals( + expected.map { it.toUByte() }, + UByteArray(size) { it.toUByte() }.runningReduce { acc, e -> (acc + e).toUByte() } + ) + assertEquals( + expected.map { it.toUShort() }, + UShortArray(size) { it.toUShort() }.runningReduce { acc, e -> (acc + e).toUShort() } + ) + assertEquals( + expected.map { it.toUInt() }, + UIntArray(size) { it.toUInt() }.runningReduce { acc, e -> acc + e } + ) + assertEquals( + expected.map { it.toULong() }, + ULongArray(size) { it.toULong() }.runningReduce { acc, e -> acc + e } + ) + } + } + + @Test + fun runningReduceIndexed() { for (size in 0 until 4) { val expected = listOf(0, 1, 6, 27).subList(0, size) assertEquals( expected.map { it.toUByte() }, - UByteArray(size) { it.toUByte() }.scanReduceIndexed { index, acc, e -> (index.toUInt() * (acc + e)).toUByte() } + UByteArray(size) { it.toUByte() }.runningReduceIndexed { index, acc, e -> (index.toUInt() * (acc + e)).toUByte() } ) assertEquals( expected.map { it.toUShort() }, - UShortArray(size) { it.toUShort() }.scanReduceIndexed { index, acc, e -> (index.toUInt() * (acc + e)).toUShort() } + UShortArray(size) { it.toUShort() }.runningReduceIndexed { index, acc, e -> (index.toUInt() * (acc + e)).toUShort() } ) assertEquals( expected.map { it.toUInt() }, - UIntArray(size) { it.toUInt() }.scanReduceIndexed { index, acc, e -> index.toUInt() * (acc + e) } + UIntArray(size) { it.toUInt() }.runningReduceIndexed { index, acc, e -> index.toUInt() * (acc + e) } ) assertEquals( expected.map { it.toULong() }, - ULongArray(size) { it.toULong() }.scanReduceIndexed { index, acc, e -> index.toULong() * (acc + e) } + ULongArray(size) { it.toULong() }.runningReduceIndexed { index, acc, e -> index.toULong() * (acc + e) } ) } } diff --git a/libraries/stdlib/test/text/StringTest.kt b/libraries/stdlib/test/text/StringTest.kt index 9ba2179ac71..4d4fa7f3322 100644 --- a/libraries/stdlib/test/text/StringTest.kt +++ b/libraries/stdlib/test/text/StringTest.kt @@ -1359,40 +1359,38 @@ class StringTest { @Test fun scan() = withOneCharSequenceArg { arg1 -> for (size in 0 until 4) { - assertEquals( - listOf("", "0", "01", "012", "0123").take(size + 1), - arg1((0 until size).joinToString(separator = "")).scan("") { acc, e -> acc + e } - ) + val source = arg1((0 until size).joinToString(separator = "")) + val expected = listOf("", "0", "01", "012", "0123").take(size + 1) + assertEquals(expected, source.scan("") { acc, e -> acc + e }) + assertEquals(expected, source.runningFold("") { acc, e -> acc + e }) } } @Test fun scanIndexed() = withOneCharSequenceArg { arg1 -> for (size in 0 until 4) { - assertEquals( - listOf("+", "+[0: a]", "+[0: a][1: b]", "+[0: a][1: b][2: c]", "+[0: a][1: b][2: c][3: d]").take(size + 1), - arg1(('a' until 'a' + size).joinToString(separator = "")).scanIndexed("+") { index, acc, e -> "$acc[$index: $e]" } - ) + val source = arg1(('a' until 'a' + size).joinToString(separator = "")) + val expected = listOf("+", "+[0: a]", "+[0: a][1: b]", "+[0: a][1: b][2: c]", "+[0: a][1: b][2: c][3: d]").take(size + 1) + assertEquals(expected, source.scanIndexed("+") { index, acc, e -> "$acc[$index: $e]" }) + assertEquals(expected, source.runningFoldIndexed("+") { index, acc, e -> "$acc[$index: $e]" }) } } @Test - fun scanReduce() = withOneCharSequenceArg { arg1 -> + fun runningReduce() = withOneCharSequenceArg { arg1 -> for (size in 0 until 4) { - assertEquals( - listOf(0, 1, 3, 6).take(size).map { it.toChar() }, - arg1((0.toChar() until size.toChar()).joinToString(separator = "")).scanReduce { acc, e -> acc + e.toInt() } - ) + val expected = listOf(0, 1, 3, 6).take(size).map { it.toChar() } + val source = arg1((0.toChar() until size.toChar()).joinToString(separator = "")) + assertEquals(expected, source.runningReduce { acc, e -> acc + e.toInt() }) } } @Test fun scanReduceIndexed() = withOneCharSequenceArg { arg1 -> for (size in 0 until 4) { - assertEquals( - listOf(0, 1, 6, 27).take(size).map { it.toChar() }, - arg1((0.toChar() until size.toChar()).joinToString(separator = "")).scanReduceIndexed { index, acc, e -> (index * (acc.toInt() + e.toInt())).toChar() } - ) + val expected = listOf(0, 1, 6, 27).take(size).map { it.toChar() } + val source = arg1((0.toChar() until size.toChar()).joinToString(separator = "")) + assertEquals(expected, source.runningReduceIndexed { index, acc, e -> (index * (acc.toInt() + e.toInt())).toChar() }) } } diff --git a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt index dc40d98cb2e..a886158dad8 100644 --- a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt +++ b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt @@ -1575,6 +1575,10 @@ public final class kotlin/collections/ArraysKt { public static final fun reversedArray ([Ljava/lang/Object;)[Ljava/lang/Object; public static final fun reversedArray ([S)[S public static final fun reversedArray ([Z)[Z + public static final fun runningFold ([Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/List; + public static final fun runningFoldIndexed ([Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Ljava/util/List; + public static final fun runningReduce ([Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/List; + public static final fun runningReduceIndexed ([Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Ljava/util/List; public static final fun scan ([Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/List; public static final fun scanIndexed ([Ljava/lang/Object;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Ljava/util/List; public static final fun scanReduce ([Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/List; @@ -2192,6 +2196,10 @@ public final class kotlin/collections/CollectionsKt { public static final fun retainAll (Ljava/util/List;Lkotlin/jvm/functions/Function1;)Z public static final fun reverse (Ljava/util/List;)V public static final fun reversed (Ljava/lang/Iterable;)Ljava/util/List; + public static final fun runningFold (Ljava/lang/Iterable;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/List; + public static final fun runningFoldIndexed (Ljava/lang/Iterable;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Ljava/util/List; + public static final fun runningReduce (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Ljava/util/List; + public static final fun runningReduceIndexed (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function3;)Ljava/util/List; public static final fun scan (Ljava/lang/Iterable;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/List; public static final fun scanIndexed (Ljava/lang/Iterable;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Ljava/util/List; public static final fun scanReduce (Ljava/lang/Iterable;Lkotlin/jvm/functions/Function2;)Ljava/util/List; @@ -4742,6 +4750,10 @@ public final class kotlin/sequences/SequencesKt { 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 runningFold (Lkotlin/sequences/Sequence;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Lkotlin/sequences/Sequence; + public static final fun runningFoldIndexed (Lkotlin/sequences/Sequence;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Lkotlin/sequences/Sequence; + public static final fun runningReduce (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function2;)Lkotlin/sequences/Sequence; + public static final fun runningReduceIndexed (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function3;)Lkotlin/sequences/Sequence; public static final fun scan (Lkotlin/sequences/Sequence;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Lkotlin/sequences/Sequence; public static final fun scanIndexed (Lkotlin/sequences/Sequence;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Lkotlin/sequences/Sequence; public static final fun scanReduce (Lkotlin/sequences/Sequence;Lkotlin/jvm/functions/Function2;)Lkotlin/sequences/Sequence; @@ -5193,6 +5205,10 @@ public final class kotlin/text/StringsKt { public static final fun replaceRange (Ljava/lang/CharSequence;IILjava/lang/CharSequence;)Ljava/lang/CharSequence; public static final fun replaceRange (Ljava/lang/CharSequence;Lkotlin/ranges/IntRange;Ljava/lang/CharSequence;)Ljava/lang/CharSequence; public static final fun reversed (Ljava/lang/CharSequence;)Ljava/lang/CharSequence; + public static final fun runningFold (Ljava/lang/CharSequence;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/List; + public static final fun runningFoldIndexed (Ljava/lang/CharSequence;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Ljava/util/List; + public static final fun runningReduce (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function2;)Ljava/util/List; + public static final fun runningReduceIndexed (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function3;)Ljava/util/List; public static final fun scan (Ljava/lang/CharSequence;Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/util/List; public static final fun scanIndexed (Ljava/lang/CharSequence;Ljava/lang/Object;Lkotlin/jvm/functions/Function3;)Ljava/util/List; public static final fun scanReduce (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function2;)Ljava/util/List; diff --git a/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt b/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt index b24bdbf04c6..fa0d5654e9d 100644 --- a/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt +++ b/libraries/tools/kotlin-stdlib-gen/src/templates/Aggregates.kt @@ -1215,12 +1215,11 @@ object Aggregates : TemplateGroupBase() { $initialValueRequirement""" } - val f_scan = fn("scan(initial: R, operation: (acc: R, T) -> R)") { + val f_runningFold = fn("runningFold(initial: R, operation: (acc: R, T) -> R)") { includeDefault() include(CharSequences, ArraysOfUnsigned) } builder { - since("1.3") - annotation("@ExperimentalStdlibApi") + since("1.4") specialFor(Iterables, ArraysOfObjects, CharSequences) { inline() } specialFor(ArraysOfPrimitives, ArraysOfUnsigned) { inlineOnly() } @@ -1238,7 +1237,7 @@ object Aggregates : TemplateGroupBase() { @param [operation] function that takes current accumulator value and ${f.element.prefixWithArticle()}, and calculates the next accumulator value. """ } - sample("samples.collections.Collections.Aggregates.scan") + sample("samples.collections.Collections.Aggregates.runningFold") sequenceClassification(intermediate, stateless) body(ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned, CharSequences) { @@ -1273,7 +1272,7 @@ object Aggregates : TemplateGroupBase() { return sequence { yield(initial) var accumulator = initial - for (element in this@scan) { + for (element in this@runningFold) { accumulator = operation(accumulator, element) yield(accumulator) } @@ -1282,7 +1281,7 @@ object Aggregates : TemplateGroupBase() { } } - val f_scanIndexed = fn("scanIndexed(initial: R, operation: (index: Int, acc: R, T) -> R)") { + val f_scan = fn("scan(initial: R, operation: (acc: R, T) -> R)") { includeDefault() include(CharSequences, ArraysOfUnsigned) } builder { @@ -1297,6 +1296,34 @@ object Aggregates : TemplateGroupBase() { returns("List") specialFor(Sequences) { returns("Sequence") } + doc { + """ + Returns a ${f.mapResult} containing successive accumulation values generated by applying [operation] from left to right + to each ${f.element} and current accumulator value that starts with [initial] value. + ${scanAccMutationNote(true, f)} + @param [operation] function that takes current accumulator value and ${f.element.prefixWithArticle()}, and calculates the next accumulator value. + """ + } + sample("samples.collections.Collections.Aggregates.scan") + sequenceClassification(intermediate, stateless) + + body { "return runningFold(initial, operation)" } + } + + val f_runningFoldIndexed = fn("runningFoldIndexed(initial: R, operation: (index: Int, acc: R, T) -> R)") { + includeDefault() + include(CharSequences, ArraysOfUnsigned) + } builder { + since("1.4") + + specialFor(Iterables, ArraysOfObjects, CharSequences) { inline() } + specialFor(ArraysOfPrimitives, ArraysOfUnsigned) { inlineOnly() } + + typeParam("R") + + returns("List") + specialFor(Sequences) { returns("Sequence") } + doc { """ Returns a ${f.mapResult} containing successive accumulation values generated by applying [operation] from left to right @@ -1306,7 +1333,7 @@ object Aggregates : TemplateGroupBase() { and the ${f.element} itself, and calculates the next accumulator value. """ } - sample("samples.collections.Collections.Aggregates.scan") + sample("samples.collections.Collections.Aggregates.runningFold") sequenceClassification(intermediate, stateless) body(ArraysOfObjects, ArraysOfPrimitives, ArraysOfUnsigned, CharSequences) { @@ -1343,7 +1370,7 @@ object Aggregates : TemplateGroupBase() { yield(initial) var index = 0 var accumulator = initial - for (element in this@scanIndexed) { + for (element in this@runningFoldIndexed) { accumulator = operation(checkIndexOverflow(index++), accumulator, element) yield(accumulator) } @@ -1352,12 +1379,41 @@ object Aggregates : TemplateGroupBase() { } } - val f_scanReduce = fn("scanReduce(operation: (acc: T, T) -> T)") { - include(ArraysOfPrimitives, ArraysOfUnsigned, CharSequences) + val f_scanIndexed = fn("scanIndexed(initial: R, operation: (index: Int, acc: R, T) -> R)") { + includeDefault() + include(CharSequences, ArraysOfUnsigned) } builder { since("1.3") annotation("@ExperimentalStdlibApi") + specialFor(Iterables, ArraysOfObjects, CharSequences) { inline() } + specialFor(ArraysOfPrimitives, ArraysOfUnsigned) { inlineOnly() } + + typeParam("R") + + returns("List") + specialFor(Sequences) { returns("Sequence") } + + doc { + """ + Returns a ${f.mapResult} containing successive accumulation values generated by applying [operation] from left to right + to each ${f.element}, its index in the original ${f.collection} and current accumulator value that starts with [initial] value. + ${scanAccMutationNote(true, f)} + @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.scan") + sequenceClassification(intermediate, stateless) + + body { "return runningFoldIndexed(initial, operation)" } + } + + val f_runningReduce = fn("runningReduce(operation: (acc: T, T) -> T)") { + include(ArraysOfPrimitives, ArraysOfUnsigned, CharSequences) + } builder { + since("1.4") + specialFor(CharSequences) { inline() } specialFor(ArraysOfPrimitives, ArraysOfUnsigned) { inlineOnly() } @@ -1371,7 +1427,7 @@ object Aggregates : TemplateGroupBase() { @param [operation] function that takes current accumulator value and ${f.element.prefixWithArticle()}, and calculates the next accumulator value. """ } - sample("samples.collections.Collections.Aggregates.scanReduce") + sample("samples.collections.Collections.Aggregates.runningReduce") body { """ @@ -1388,11 +1444,10 @@ object Aggregates : TemplateGroupBase() { } } - val f_scanReduceIndexed = fn("scanReduceIndexed(operation: (index: Int, acc: T, T) -> T)") { + val f_runningReduceIndexed = fn("runningReduceIndexed(operation: (index: Int, acc: T, T) -> T)") { include(ArraysOfPrimitives, ArraysOfUnsigned, CharSequences) } builder { - since("1.3") - annotation("@ExperimentalStdlibApi") + since("1.4") specialFor(CharSequences) { inline() } specialFor(ArraysOfPrimitives, ArraysOfUnsigned) { inlineOnly() } @@ -1408,7 +1463,7 @@ object Aggregates : TemplateGroupBase() { and the ${f.element} itself, and calculates the next accumulator value. """ } - sample("samples.collections.Collections.Aggregates.scanReduce") + sample("samples.collections.Collections.Aggregates.runningReduce") body { """ @@ -1425,7 +1480,7 @@ object Aggregates : TemplateGroupBase() { } } - val f_scanReduceSuper = fn("scanReduce(operation: (acc: S, T) -> S)") { + val f_runningReduceSuper = fn("runningReduce(operation: (acc: S, T) -> S)") { include(ArraysOfObjects, Iterables, Sequences) } builder { since("1.3") @@ -1447,7 +1502,7 @@ object Aggregates : TemplateGroupBase() { @param [operation] function that takes current accumulator value and the ${f.element}, and calculates the next accumulator value. """ } - sample("samples.collections.Collections.Aggregates.scanReduce") + sample("samples.collections.Collections.Aggregates.runningReduce") sequenceClassification(intermediate, stateless) body(ArraysOfObjects) { @@ -1494,11 +1549,10 @@ object Aggregates : TemplateGroupBase() { } } - val f_scanReduceIndexedSuper = fn("scanReduceIndexed(operation: (index: Int, acc: S, T) -> S)") { + val f_runningReduceIndexedSuper = fn("runningReduceIndexed(operation: (index: Int, acc: S, T) -> S)") { include(ArraysOfObjects, Iterables, Sequences) } builder { - since("1.3") - annotation("@ExperimentalStdlibApi") + since("1.4") specialFor(ArraysOfObjects, Iterables) { inline() } @@ -1517,7 +1571,7 @@ object Aggregates : TemplateGroupBase() { and the ${f.element} itself, and calculates the next accumulator value. """ } - sample("samples.collections.Collections.Aggregates.scanReduce") + sample("samples.collections.Collections.Aggregates.runningReduce") sequenceClassification(intermediate, stateless) body(ArraysOfObjects) { @@ -1566,6 +1620,73 @@ object Aggregates : TemplateGroupBase() { } } + + val f_scanReduce = fn("scanReduce(operation: (acc: T, T) -> T)") { + include(ArraysOfPrimitives, ArraysOfUnsigned, CharSequences) + } builder { + since("1.3") + annotation("@ExperimentalStdlibApi") + deprecate(Deprecation("Use runningReduce instead.", "runningReduce(operation)", DeprecationLevel.WARNING)) + + specialFor(CharSequences) { inline() } + specialFor(ArraysOfPrimitives, ArraysOfUnsigned) { inlineOnly() } + + returns("List") + + body { "return runningReduce(operation)" } + } + + val f_scanReduceIndexed = fn("scanReduceIndexed(operation: (index: Int, acc: T, T) -> T)") { + include(ArraysOfPrimitives, ArraysOfUnsigned, CharSequences) + } builder { + since("1.3") + annotation("@ExperimentalStdlibApi") + deprecate(Deprecation("Use runningReduceIndexed instead.", "runningReduceIndexed(operation)", DeprecationLevel.WARNING)) + + specialFor(CharSequences) { inline() } + specialFor(ArraysOfPrimitives, ArraysOfUnsigned) { inlineOnly() } + + returns("List") + + body { "return runningReduceIndexed(operation)" } + } + + val f_scanReduceSuper = fn("scanReduce(operation: (acc: S, T) -> S)") { + include(ArraysOfObjects, Iterables, Sequences) + } builder { + since("1.3") + annotation("@ExperimentalStdlibApi") + deprecate(Deprecation("Use runningReduce instead.", "runningReduce(operation)", DeprecationLevel.WARNING)) + + specialFor(ArraysOfObjects, Iterables) { inline() } + + typeParam("S") + typeParam("T : S") + + returns("List") + specialFor(Sequences) { returns("Sequence") } + body { "return runningReduce(operation)" } + } + + val f_scanReduceIndexedSuper = fn("scanReduceIndexed(operation: (index: Int, acc: S, T) -> S)") { + include(ArraysOfObjects, Iterables, Sequences) + } builder { + since("1.3") + annotation("@ExperimentalStdlibApi") + deprecate(Deprecation("Use runningReduceIndexed instead.", "runningReduceIndexed(operation)", DeprecationLevel.WARNING)) + + specialFor(ArraysOfObjects, Iterables) { inline() } + + typeParam("S") + typeParam("T : S") + + returns("List") + specialFor(Sequences) { returns("Sequence") } + + body { "return runningReduceIndexed(operation)" } + + } + val f_onEach = fn("onEach(action: (T) -> Unit)") { includeDefault() include(Maps, CharSequences, ArraysOfUnsigned)