Kotlin Academy · 课时

fold、reduce 与 runningFold

使用 fold、reduce 和累加函数聚合集合元素。

第 3 / 4 课14 个步骤

fold、reduce 与 runningFold 是 CoddyKit 上的免费 Kotlin Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Kotlin Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Kotlin Academy 课程共包含 4 节课。

聚合操作

fold 和归约会将集合聚合为单个值。fold 接受一个种子值;归约使用第一个元素作为种子值。runningFold 会返回每个中间结果。

基础 fold

fold(seed) { acc, x -> ... } 从种子值开始,将每个元素与累加器组合。

fun main() {
    val nums = listOf(1, 2, 3, 4)
    val sum = nums.fold(0) { acc, n -> acc + n }
    println(sum) // 10
}

使用非数值种子进行 fold

种子值可以是任意类型。fold 可以将 List<T> 转换为完全不同的结果。

fun main() {
    val words = listOf("hello", "world", "kotlin")
    val joined = words.fold("") { acc, w -> if (acc.isEmpty()) w else "$acc, $w" }
    println(joined) // hello, world, kotlin
}

基础归约

reduce 使用第一个元素作为种子值。lambda 每次组合两个元素。

fun main() {
    val nums = listOf(2, 3, 4, 5)
    val product = nums.reduce { acc, n -> acc * n }
    println(product) // 120
}

对空列表进行归约会抛出异常

reduce 要求至少有一个元素。为确保安全,请使用 reduceOrNull,或优先使用带种子值的 fold。

fun main() {
    val empty: List<Int> = emptyList()
    println(empty.reduceOrNull { a, b -> a + b }) // null
    println(empty.fold(0) { a, b -> a + b })       // 0
}

fold 与归约

当您需要不同的结果类型或默认值时,请使用 fold。当结果类型与元素类型一致且列表至少包含一个元素时,请使用归约。

fun main() {
    val nums = listOf(1, 2, 3, 4)
    println(nums.reduce { a, b -> a + b })       // 10
    println(nums.fold(100) { a, b -> a + b })   // 110 (seed 100)
}

runningFold

runningFold 会返回每个中间累加器的列表——适用于累积求和和逐步处理流水线。

fun main() {
    val nums = listOf(1, 2, 3, 4)
    val running = nums.runningFold(0) { acc, n -> acc + n }
    println(running) // [0, 1, 3, 6, 10]
}

累积求和示例

一种常见的分析模式:逐月累积总额。

fun main() {
    val monthly = listOf(100, 150, 80, 200, 120)
    val cumulative = monthly.runningReduce { acc, x -> acc + x }
    println(cumulative) // [100, 250, 330, 530, 650]
}

使用 fold 构建映射

通过累积到可变映射中,使用 fold 将列表聚合为一个 Map。

fun main() {
    val words = listOf("apple", "banana", "cherry")
    val byLetter = words.fold(mutableMapOf<Char, MutableList<String>>()) { acc, w ->
        val key = w[0]
        acc.getOrPut(key) { mutableListOf() }.add(w)
        acc
    }
    println(byLetter)
}

使用 fold 构建列表

fold 可以将序列转换为结构化列表——例如,将连续的重复项分组。

fun main() {
    val nums = listOf(1, 1, 2, 3, 3, 3, 4)
    val grouped = nums.fold(mutableListOf<MutableList<Int>>()) { acc, n ->
        if (acc.isEmpty() || acc.last().last() != n) acc.add(mutableListOf(n))
        else acc.last().add(n)
        acc
    }
    println(grouped) // [[1, 1], [2], [3, 3, 3], [4]]
}

foldIndexed

将索引与每个元素一同传递——适用于需要考虑位置的聚合。

fun main() {
    val nums = listOf(10, 20, 30)
    val weighted = nums.foldIndexed(0) { i, acc, n -> acc + (i + 1) * n }
    // 1*10 + 2*20 + 3*30 = 140
    println(weighted)
}

reduceRight

reduceRight 会从右到左进行聚合。当操作不满足交换律时,这一点很重要(例如字符串连接的顺序)。

fun main() {
    val words = listOf("a", "b", "c", "d")
    val leftToRight = words.reduce { acc, w -> "$acc-$w" }
    val rightToLeft = words.reduceRight { w, acc -> "$w-$acc" }
    println(leftToRight)   // a-b-c-d
    println(rightToLeft)   // a-b-c-d (same here but operation matters)
}

快速检查

哪个函数会返回包含每个中间累加器值的列表?

回顾

fold 使用种子值进行聚合(种子值可以是任意类型)。归约使用第一个元素作为种子值(集合不能为空)。runningFold / runningReduce 会返回每个中间值。可以使用这些函数进行求和、求积、构建映射、分组和逐步转换。

免费开始

用 AI 导师学习 Kotlin — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
51
课程
203

常见问题解答

「fold、reduce 与 runningFold」课时是免费的吗?

是的 — 「fold、reduce 与 runningFold」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Kotlin Academy 课程的其余内容,请升级到 CoddyKit PRO。 Kotlin Academy 课程共包含 4 节课。

「fold、reduce 与 runningFold」这节课中我会学到什么?

使用 fold、reduce 和累加函数聚合集合元素。 你通过在浏览器中直接运行的动手代码来练习 Kotlin Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Kotlin Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Kotlin Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「fold、reduce 与 runningFold」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Kotlin Academy 课中编写并运行代码吗?

能。每节 Kotlin Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. map 与 flatMap:转换每个元素
  2. filter、filterNot 与 partition
  3. fold、reduce 与 runningFold
  4. 串联处理流程并使用 Sequence 避免中间列表
← 返回 Kotlin Academy