Kotlin的fold/reduce如何实现双累加器消除外部变量副作用
完全可以实现,你只需要把 fold 的累加器换成可以同时存两个值的结构即可,全程不需要外部可变变量,完全无副作用。
最简实现(用 Pair 存两个累加值)
val data = listOf("F 1", "D 2", "U 1", "D 3", "F 10") val (result, _) = data.fold(0 to 0) { (acc, acc2), str -> val (op, numStr) = str.split(" ") val num = numStr.toInt() when (op) { "F" -> (acc + num * acc2) to acc2 "D" -> acc to (acc2 + num) "U" -> acc to (acc2 - num) else -> acc to acc2 } }
说明:
- fold 初始值传入
Pair(0, 0),第一个元素对应你原来的结果累加器,第二个元素对应原来的acc2 - 每一步操作都返回新的 Pair 实例,没有任何可变变量修改,纯函数逻辑
- 最终通过解构赋值直接拿到最终结果,无用的第二个累加值用下划线占位即可
可读性更高的实现(自定义累加器类)
如果怕 Pair 两个字段的含义混淆,可以自定义数据类做累加器:
// 字段名可以根据实际业务含义调整,这里假设acc2是深度参数 data class AccState(val result: Int, val depth: Int) val data = listOf("F 1", "D 2", "U 1", "D 3", "F 10") val result = data.fold(AccState(0, 0)) { state, str -> val (op, numStr) = str.split(" ") val num = numStr.toInt() when (op) { "F" -> state.copy(result = state.result + num * state.depth) "D" -> state.copy(depth = state.depth + num) "U" -> state.copy(depth = state.depth - num) else -> state } }.result
内容的提问来源于stack exchange,提问作者infinitesimal
相关产品推荐
相关产品推荐

