聚合操作
Table of Contents
Kotlin 集合包含用于常用的 聚合操作 (基于集合内容返回单个值的操作)的函数:
- minOrNull() 与 maxOrNull() 分别返回最小和最大的元素
- average() 返回数字集合中元素的平均值
- sum() 返回数字集合中元素的总和
- count() 返回集合中元素的数量
fun main() { //sampleStart val numbers = listOf(6, 42, 10, 4) println("Count: ${numbers.count()}") println("Max: ${numbers.maxOrNull()}") println("Min: ${numbers.minOrNull()}") println("Average: ${numbers.average()}") println("Sum: ${numbers.sum()}") //sampleEnd }
还有一些通过某些选择器函数或自定义 Comparator 来检索最小和最大元素的函数。
- maxByOrNull() / minByOrNull() 接受一个 选择器函数 并返回使选择器返回最大或最小值的元素
- maxWithOrNull() / minWithOrNull() 接受一个 Comparator 对象 并且根据此 Comparator 对象返回最大或最小元素
fun main() { //sampleStart val numbers2 = listOf(5, 42, 10, 4) val min3Remainder = numbers2.minByOrNull { it % 3 } println(min3Remainder) val strings = listOf("one", "two", "three", "four") val longestString = strings.maxWithOrNull(compareBy { it.length }) println(longestString) //sampleEnd }
Fold 与 reduce
对于更特定的情况,有函数 reduce() 和 fold() ,它们依次将所提供的操作应用于集合元素并返回累积的结果。 操作有两个参数:先前的累积值和集合元素。这两个函数的区别在于:
- fold() 接受一个 初始值 并将其用作第一步的累积值
- reduce() 的第一步则将 第一个 和 第二个元素 作为第一步的操作参数
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() 和 foldRight() 它们的工作方式类似于 fold() 和 reduce(),但从最后一个元素开始,然后再继续到前一个元素
fun main() { //sampleStart val numbers = listOf(5, 2, 10, 4) val sumDoubledRight = numbers.foldRight(0) { element, sum -> sum + element * 2 } println(sumDoubledRight) //sampleEnd }
记住,在使用 foldRight 或 reduceRight 时,操作参数会更改其顺序:第一个参数变为元素,然后第二个参数变为累积值
还可以使用将 元素索引 作为参数的操作。 为此,使用函数 reduceIndexed() 和 foldIndexed() 传递元素索引作为操作的第一个参数。最后,还有将这些操作从右到左应用于集合元素的函数 reduceRightIndexed() 与 foldRightIndexed()
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 }
Next:更改 | Previous:排序 | Home:集合 |