集合聚合操作

    • max() 分别返回最小和最大的元素;
    • 返回数字集合中元素的平均值;
    • sum() 返回数字集合中元素的总和;
    • 返回集合中元素的数量;

    还有一些通过某些选择器函数或自定义 Comparator 来检索最小和最大元素的函数。

    • /minBy() 接受一个选择器函数并返回使选择器返回最大或最小值的元素。
    • /minWith() 接受一个 Comparator 对象并且根据此 Comparator 对象返回最大或最小元素。
    1. fun main() {
    2. //sampleStart
    3. val numbers = listOf(5, 42, 10, 4)
    4. val min3Remainder = numbers.minBy { it % 3 }
    5. println(min3Remainder)
    6. val strings = listOf("one", "two", "three", "four")
    7. val longestString = strings.maxWith(compareBy { it.length })
    8. //sampleEnd
    9. }

    此外,有一些高级的求和函数,它们接受一个函数并返回对所有元素调用此函数的返回值的总和:

    • 使用对集合元素调用返回 Int 值的函数。
    • sumByDouble() 与返回 Double 的函数一起使用。

    这两个函数的区别在于:fold() 接受一个初始值并将其用作第一步的累积值,而 reduce() 的第一步则将第一个和第二个元素作为第一步的操作参数。

    1. fun main() {
    2. //sampleStart
    3. val numbers = listOf(5, 2, 10, 4)
    4. val sum = numbers.reduce { sum, element -> sum + element }
    5. println(sum)
    6. val sumDoubled = numbers.fold(0) { sum, element -> sum + element * 2 }
    7. println(sumDoubled)
    8. //val sumDoubledReduce = numbers.reduce { sum, element -> sum + element * 2 } //错误:第一个元素在结果中没有加倍
    9. //println(sumDoubledReduce)
    10. }

    上面的实例展示了区别:fold() 用于计算加倍的元素之和。 如果将相同的函数传给 reduce(),那么它会返回另一个结果,因为在第一步中它将列表的第一个和第二个元素作为参数,所以第一个元素不会被加倍。

    你还可以使用将元素索引作为参数的操作。 为此,使用函数 和 foldIndexed() 传递元素索引作为操作的第一个参数。

    最后,还有将这些操作从右到左应用于集合元素的函数—— 与 foldRightIndexed()

    1. fun main() {
    2. //sampleStart
    3. val numbers = listOf(5, 2, 10, 4)
    4. val sumEven = numbers.foldIndexed(0) { idx, sum, element -> if (idx % 2 == 0) sum + element else sum }
    5. println(sumEven)
    6. val sumEvenRight = numbers.foldRightIndexed(0) { idx, element, sum -> if (idx % 2 == 0) sum + element else sum }
    7. println(sumEvenRight)
    8. //sampleEnd
    9. }