助力软件开发企业降本增效 PHP / java源码系统,只需一次付费,代码终身使用! 广告
# 集合聚合操作 [TOC] Kotlin 集合包含用于常用的 _聚合操作_ (基于集合内容返回单个值的操作)的函数 。其中大多数是众所周知的,并且其工作方式与在其他语言中相同。 * [`min()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/min.html) 与 [`max()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/max.html) 分别返回最小和最大的元素; * [`average()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/average.html) 返回数字集合中元素的平均值; * [`sum()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sum.html) 返回数字集合中元素的总和; * [`count()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/count.html) 返回集合中元素的数量; ```kotlin fun main() { //sampleStart val numbers = listOf(6, 42, 10, 4) println("Count: ${numbers.count()}") println("Max: ${numbers.max()}") println("Min: ${numbers.min()}") println("Average: ${numbers.average()}") println("Sum: ${numbers.sum()}") //sampleEnd } ``` 还有一些通过某些选择器函数或自定义 [`Comparator`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-comparator/index.html) 来检索最小和最大元素的函数。 * [`maxBy()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/max-by.html)/[`minBy()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/min-by.html) 接受一个选择器函数并返回使选择器返回最大或最小值的元素。 * [`maxWith()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/max-with.html)/[`minWith()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/min-with.html) 接受一个 `Comparator` 对象并且根据此 `Comparator` 对象返回最大或最小元素。 ```kotlin fun main() { //sampleStart val numbers = listOf(5, 42, 10, 4) val min3Remainder = numbers.minBy { it % 3 } println(min3Remainder) val strings = listOf("one", "two", "three", "four") val longestString = strings.maxWith(compareBy { it.length }) println(longestString) //sampleEnd } ``` 此外,有一些高级的求和函数,它们接受一个函数并返回对所有元素调用此函数的返回值的总和: * [`sumBy()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sum-by.html) 使用对集合元素调用返回 `Int` 值的函数。 * [`sumByDouble()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sum-by-double.html) 与返回 `Double` 的函数一起使用。 ```kotlin fun main() { //sampleStart val numbers = listOf(5, 42, 10, 4) println(numbers.sumBy { it * 2 }) println(numbers.sumByDouble { it.toDouble() / 2 }) //sampleEnd } ``` ## Fold 与 reduce 对于更特定的情况,有函数 [`reduce()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/reduce.html) 和 [`fold()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/fold.html),它们依次将所提供的操作应用于集合元素并返回累积的结果。操作有两个参数:先前的累积值和集合元素。 这两个函数的区别在于:`fold()` 接受一个初始值并将其用作第一步的累积值,而 `reduce()` 的第一步则将第一个和第二个元素作为第一步的操作参数。 ```kotlin fun main() { //sampleStart val numbers = listOf(5, 2, 10, 4) val sum = numbers.reduce { sum, element -> sum + element } println(sum) val sumDoubled = numbers.fold(0) { sum, element -> sum + element * 2 } println(sumDoubled) //val sumDoubledReduce = numbers.reduce { sum, element -> sum + element * 2 } //错误:第一个元素在结果中没有加倍 //println(sumDoubledReduce) //sampleEnd } ``` 上面的实例展示了区别:`fold()` 用于计算加倍的元素之和。如果将相同的函数传给 `reduce()`,那么它会返回另一个结果,因为在第一步中它将列表的第一个和第二个元素作为参数,所以第一个元素不会被加倍。 如需将函数以相反的顺序应用于元素,可以使用函数 [`reduceRight()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/reduce-right.html) 和 [`foldRight()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/fold-right.html)。它们的工作方式类似于 `fold()` 和 `reduce()`,但从最后一个元素开始,然后再继续到前一个元素。记住,在使用 foldRight 或 reduceRight 时,操作参数会更改其顺序:第一个参数变为元素,然后第二个参数变为累积值。 ```kotlin fun main() { //sampleStart val numbers = listOf(5, 2, 10, 4) val sumDoubledRight = numbers.foldRight(0) { element, sum -> sum + element * 2 } println(sumDoubledRight) //sampleEnd } ``` 你还可以使用将元素索引作为参数的操作。为此,使用函数 [`reduceIndexed()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/reduce-indexed.html) 和 [`foldIndexed()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/fold-indexed.html) 传递元素索引作为操作的第一个参数。 最后,还有将这些操作从右到左应用于集合元素的函数——[`reduceRightIndexed()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/reduce-right-indexed.html) 与 [`foldRightIndexed()`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/fold-right-indexed.html)。 ```kotlin fun main() { //sampleStart val numbers = listOf(5, 2, 10, 4) val sumEven = numbers.foldIndexed(0) { idx, sum, element -> if (idx % 2 == 0) sum + element else sum } println(sumEven) val sumEvenRight = numbers.foldRightIndexed(0) { idx, element, sum -> if (idx % 2 == 0) sum + element else sum } println(sumEvenRight) //sampleEnd } ```