Kotlin中如何简化多嵌套循环生成Transformation列表?
嘿,这个问题问得太对了——深层嵌套的for循环确实看着头疼,Kotlin的函数式API正好能帮我们把这段代码变得更简洁清爽!下面给你几种不同的实现方式,都能达到和原代码一样的效果:
方法1:用
buildList + forEach优化可读性 这是最贴近你原始逻辑的写法,只是把传统的for循环换成了forEach,用Kotlin标准库的buildList来构建结果列表。它保留了原有的逻辑顺序,视觉上的嵌套层级更清晰,还避免了显式创建ArrayList的冗余:
val allTransformations = buildList { (0..4).forEach { moveZ -> (0..4).forEach { moveY -> (0..4).forEach { moveX -> (0..3).forEach { rotateZ -> (0..3).forEach { rotateY -> (0..3).forEach { rotateX -> add(Transformation(rotateX, rotateY, rotateZ, moveX, moveY, moveZ)) } } } } } } }
这种写法的好处是学习成本低,逻辑和原代码完全一致,可读性拉满,不需要额外理解复杂的函数式操作。
方法2:用
flatMap实现函数式风格 如果想更偏向函数式编程,可以用flatMap逐层展开每个范围的元素,最后用map生成Transformation对象:
val allTransformations = (0..4).flatMap { moveZ -> (0..4).flatMap { moveY -> (0..4).flatMap { moveX -> (0..3).flatMap { rotateZ -> (0..3).flatMap { rotateY -> (0..3).map { rotateX -> Transformation(rotateX, rotateY, rotateZ, moveX, moveY, moveZ) } } } } } }
这里每一层flatMap都会把当前范围的元素和上一层的结果组合起来,自动处理集合的拼接,不需要手动调用add。虽然还是有嵌套,但比原始的for循环更符合函数式编程的风格。
方法3:自定义笛卡尔积扩展函数(最简洁)
如果你的代码里经常需要处理这种多集合的笛卡尔积场景,自定义一个扩展函数能让代码变得异常简洁:
首先定义扩展函数(可以放在工具类里复用):
fun <T> List<Iterable<T>>.cartesianProduct(): List<List<T>> = if (isEmpty()) emptyList() else drop(1).fold(first().map { listOf(it) }) { acc, iterable -> acc.flatMap { list -> iterable.map { list + it } } }
然后就可以这样使用:
// 按原循环顺序定义所有需要遍历的范围:moveZ, moveY, moveX, rotateZ, rotateY, rotateX val ranges = listOf(0..4, 0..4, 0..4, 0..3, 0..3, 0..3) val allTransformations = ranges.cartesianProduct() .map { (moveZ, moveY, moveX, rotateZ, rotateY, rotateX) -> Transformation(rotateX, rotateY, rotateZ, moveX, moveY, moveZ) }
这种写法把“生成所有组合”的逻辑完全封装起来,主代码只需要关注如何把组合转换成目标对象,非常清爽,也方便后续复用。
内容的提问来源于stack exchange,提问作者Michiel
相关产品推荐
相关产品推荐

