Kotlin 减少嵌套循环的可能性

Kotlin 减少嵌套循环的可能性,kotlin,Kotlin,在创建所有可能的转换的列表时,我想绕过几个for循环的深度嵌套 现在,使用这段代码: val allTransformations = ArrayList<Transformation>().apply { for (moveZ in 0..4) for (moveY in 0..4) for (moveX in 0..4) for (rotateZ in 0..3)

在创建所有可能的
转换的列表时,我想绕过几个for循环的深度嵌套

现在,使用这段代码:

val allTransformations = ArrayList<Transformation>().apply {
    for (moveZ in 0..4)
        for (moveY in 0..4)
            for (moveX in 0..4)
                for (rotateZ in 0..3)
                    for (rotateY in 0..3)
                        for (rotateX in 0..3)
                            add(Transformation(rotateX, rotateY, rotateZ, moveX, moveY, moveZ))
}
val allTransformations=ArrayList()。应用{
for(在0..4中移动Z)
用于(在0..4中移动)
用于(0..4中的移动X)
用于(旋转方向为0..3)
用于(旋转方向为0..3)
用于(0..3中的rotateX)
添加(变换(rotateX、rotateY、rotateZ、moveX、moveY、moveZ))
}
虽然这很简单,但我想知道Kotlin是否提供了其他工具来在一行中编写这篇文章


我想用更少的代码检索相同的列表,看看这是否会导致更少的混乱。

此解决方案可以通过以下方式调用:

loopOverRanges(0..4, 0..4, 0..4, 0..3, 0..3, 0..3) { result ->
//    result[0], result[1], result[2], result[3], result[4], result[5]
}
其定义如下:

fun loopOverRanges(
    vararg ranges: IntRange,
    function: (IntArray) -> Unit
) {
    val result = IntArray(ranges.size) { index -> ranges[index].first }

    val productOfRangeLengths = ranges
        .map { it.toList().size }
        .product()

    for (i in 0 until productOfRangeLengths) {
        function(result)

        result[0] += ranges[0].step
        for (rangeIndex in 0 until ranges.size - 1) {
            if (result[rangeIndex] == ranges[rangeIndex].last) {
                result[rangeIndex] = ranges[rangeIndex].first
                result[rangeIndex + 1] += ranges[rangeIndex].step
            }
        }
    }
}
至少可以说,这是否能提高可读性是值得怀疑的。它消除了嵌套的需要,这对于大量范围都很有用。它不会立即识别我的初始嵌套循环;它还隐藏命名参数,并可能在检索结果[TOO_HIGH_INT]时抛出IndexOutOfBounds


这是一个有趣的小调查,但我倾向于不使用它。

以下是如何使用一个循环。就像用6位数递增计数器一样。当第一个数字溢出时,进位到第二个数字并重置第一个数字。等等

fun loopOverRanges(a:IntRange,b:IntRange,c:IntRange,d:IntRange,e:IntRange,f:IntRange) : ArrayList<Transformation>
{

    val x = a.count() * b.count() * c.count() * d.count() * e.count() * f.count()
    val list : ArrayList<Transformation> = ArrayList()
    var rx = f.first
    var ry = e.first
    var rz = d.first
    var mx = c.first
    var my = b.first
    var mz = a.first
    for(i in 0 until x)
    {
        list.add(Transformation(rx,ry,rz,mx,my,mz))
        when{
            rx < f.last -> rx += 1
            ry < e.last -> {
                rx = f.first
                ry += 1
            }
            rz < d.last -> {
                rx = f.first
                ry = e.first
                rz += 1
            }
            mx < c.last -> {
                rx = f.first
                ry = e.first
                rz = d.first
                mx += 1
            }
            my < b.last -> {
                rx = f.first
                ry = e.first
                rz = d.first
                mx = c.first
                my += 1
            }
            mz < a.last -> {
                rx = f.first
                ry = e.first
                rz = d.first
                mx = c.first
                my = b.first
                mz += 1
            }
        }
        }
    }
    return list
}
fun loopOverRanges(a:IntRange,b:IntRange,c:IntRange,d:IntRange,e:IntRange,f:IntRange):数组列表
{
valx=a.count()*b.count()*c.count()*d.count()*e.count()*f.count()
val列表:ArrayList=ArrayList()
var rx=f.first
var ry=e.first
var rz=d.first
var mx=c
var my=b
var mz=a.首先
对于(从0到x的i)
{
添加(转换(rx、ry、rz、mx、my、mz))
什么时候{
rxrx+=1
ry{
rx=f
ry+=1
}
rz{
rx=f
ry=e.第一
rz+=1
}
mx{
rx=f
ry=e.第一
rz=d
mx+=1
}
我的{
rx=f
ry=e.第一
rz=d
mx=c
我的+=1
}
mz{
rx=f
ry=e.第一
rz=d
mx=c
我的=b
mz+=1
}
}
}
}
返回列表
}
它可以简化为

fun loopOverRanges(a:IntRange,b:IntRange,c:IntRange,d:IntRange,e:IntRange,f:IntRange) : ArrayList<Transformation>
{
    data class Digit(var value :Int, val range:IntRange)
    val list : ArrayList<Transformation> = ArrayList()
    val digits = arrayOf(Digit(a.first,a),Digit(b.first,b),Digit(c.first,c),Digit(d.first,d),Digit(e.first,e),Digit(f.first,f))
    val x = digits.fold(1){acc,digit -> acc * digit.range.count() }
    for(i in 0 until x)
    {
        list.add(Transformation(digits[5].value,digits[4].value,digits[3].value,digits[2].value,digits[1].value,digits[0].value))
        val j = digits.indexOfFirst { it.value < it.range.last }
        if(j >= 0)
        {
            for(k in 0 until j )
            {
                digits[k].value = digits[k].range.first
            }
            digits[j].value += 1
        }
    }
    return list
}
fun loopOverRanges(a:IntRange,b:IntRange,c:IntRange,d:IntRange,e:IntRange,f:IntRange):数组列表
{
数据类数字(var值:Int,val范围:IntRange)
val列表:ArrayList=ArrayList()
val digits=arrayOf(数字(a.first,a)、数字(b.first,b)、数字(c.first,c)、数字(d.first,d)、数字(e.first,e)、数字(f.first,f))
val x=digits.fold(1){acc,digit->acc*digit.range.count()}
对于(从0到x的i)
{
添加(转换(数字[5]。值,数字[4]。值,数字[3]。值,数字[2]。值,数字[1]。值,数字[0]。值))
val j=digits.indexOfFirst{it.value=0)
{
对于(从0到j的k)
{
数字[k]。值=数字[k]。范围。第一个
}
数字[j]。值+=1
}
}
返回列表
}

您如何想象自定义功能更简单?特别是当你需要为每个循环分配变量,而且它们的大小也不一样的时候。诚实的回答:我不知道。更具创造性的回答:类似于
循环(0..4,0..4,0..3,0..3,0..3){a,b,c,d,e,f->allTransformations.add(Transformation(a,b,c,d,e,f))}
谢谢!然而,这是一个类似于我自己的解决方案,它还将一组范围组合到一个计数器。这两种解决方案都不能满足更少代码和更少混乱的要求。因此,我将保留嵌套循环。谢谢你的意见。