Introduce runningFold and runningReduce operations

runningFold is a synonym for scan,
runningReduce replaces scanReduce.

#KT-38060
This commit is contained in:
Ilya Gorbunov
2020-04-14 14:34:02 +03:00
parent 37277d71de
commit 893021f22b
13 changed files with 1551 additions and 516 deletions
@@ -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;
@@ -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<R>")
specialFor(Sequences) { returns("Sequence<R>") }
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<R>")
specialFor(Sequences) { returns("Sequence<R>") }
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<R>")
specialFor(Sequences) { returns("Sequence<R>") }
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<T>")
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<T>")
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<S>")
specialFor(Sequences) { returns("Sequence<S>") }
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<S>")
specialFor(Sequences) { returns("Sequence<S>") }
body { "return runningReduceIndexed(operation)" }
}
val f_onEach = fn("onEach(action: (T) -> Unit)") {
includeDefault()
include(Maps, CharSequences, ArraysOfUnsigned)