Kotlin中如何基于谓词将列表拆分为连续分组?
Kotlin 连续元素分组的函数式实现
最快实现方案(计数版本,性能最优)
直接使用Kotlin标准库的fold扩展函数实现,代码如下:
val l = listOf(1, 2, 2, 2, 2, 1, 1, 1, 2, 2) val countResult = l.fold(mutableListOf<Pair<Int, Int>>()) { acc, num -> if (acc.isNotEmpty() && acc.last().first == num) { val (key, count) = acc.removeLast() acc.add(key to count + 1) } else { acc.add(num to 1) } acc } // 输出结果:[(1, 1), (2, 4), (1, 3), (2, 2)]
子列表分组版本
如果需要输出嵌套子列表的格式,实现逻辑类似:
val sublistResult = l.fold(mutableListOf<MutableList<Int>>()) { acc, num -> if (acc.isNotEmpty() && acc.last().last() == num) { acc.last().add(num) } else { acc.add(mutableListOf(num)) } acc } // 输出结果:[[1], [2, 2, 2, 2], [1, 1, 1], [2, 2]]
通用Predicate封装
如果需要复用逻辑,可封装为通用列表扩展函数,支持自定义相邻元素的分组判断规则:
fun <T> List<T>.groupConsecutiveBy(shouldGroup: (prev: T, curr: T) -> Boolean): List<List<T>> { return fold(mutableListOf<MutableList<T>>()) { acc, curr -> when { acc.isEmpty() -> acc.add(mutableListOf(curr)) shouldGroup(acc.last().last(), curr) -> acc.last().add(curr) else -> acc.add(mutableListOf(curr)) } acc } } // 调用示例:按相邻元素是否相等分组 val result = l.groupConsecutiveBy { prev, curr -> prev == curr }
- 注:
fold是Kotlin标准库原生提供的聚合函数,实现性能和手写循环基本一致,完全符合函数式编程风格,不需要引入额外依赖。
内容的提问来源于stack exchange,提问作者jlengrand
相关产品推荐
相关产品推荐

