Edit Page

分组(Grouping)

最终更新: 2024/03/21

Kotlin 标准库提供了扩展函数, 用于对集合中的元素进行分组操作. 最基本的函数是 groupBy(), 它接受一个 lambda 函数为参数, 返回结果是一个 Map. 在这个 map 中, 每个键(key)是 lambda 函数的一个返回结果, 与键(key)对应的值(value) 是一个 List, 其中包含返回这个结果的所有元素. 这个函数的用途, 举例来说, 我们可以对一个 String 组成的 list, 按字符串的首字母进行分组.

调用 groupBy() 函数时, 也可以使用另一个 lambda 函数作为第二个参数 – 这个函数负责对值进行变换. 象这样使用两个 lambda 函数调用 groupBy()时, 结果 map 中, 第一个参数(keySelector lambda 函数)负责生成键(key), 它对应的值(value) 则是由第二个参数(值转换 lambda 函数)产生的结果组成的 list, 而不是集合中原来元素组成的 list.


fun main() {
//sampleStart
    val numbers = listOf("one", "two", "three", "four", "five")

    println(numbers.groupBy { it.first().uppercase() })
    println(numbers.groupBy(keySelector = { it.first() }, valueTransform = { it.uppercase() }))
//sampleEnd
}

如果你希望对元素分组, 同时对所有的分组结果执行某个操作, 可以使用 groupingBy() 函数. 这个函数返回一个 Grouping 类型的实例. 这个 Grouping 实例可以用来对所有分组结果以 lazy 模式执行操作: 只有在操作执行之前才会真正创建分组结果.

Grouping 支持以下操作:

  • eachCount() 函数, 计算每个分组结果中的元素个数.
  • fold()reduce() 函数, 将每个分组结果作为独立的集合, 执行 折叠(fold) 与 简化(reduce) 操作, 并返回结果.
  • aggregate() 函数, 对每个分组结果中的所有元素反复执行指定的操作, 并返回最后结果. 这是对 Grouping 执行任意操作的通用方式. 如果 折叠(fold) 与 简化(reduce) 不能满足你的需求, 可以用这种方式实现自定义的操作.

fun main() {
//sampleStart
    val numbers = listOf("one", "two", "three", "four", "five", "six")
    println(numbers.groupingBy { it.first() }.eachCount())
//sampleEnd
}