arrays - 在 Kotlin 中使用嵌套 for 循环导航多维数组

标签 arrays for-loop multidimensional-array kotlin

我经常浏览像素的二维图像矩阵或三维体积数据集。通常,底层数据结构是某种基本类型的一维数组,例如 Double 或 Int。多维性质是通过嵌套的 for 循环来导航的,如下所示。

鉴于 Kotlin 目前不支持典型的 C 和 Java 式的 for 循环结构,因此似乎失去了一些灵活性。我想知道是否有一个聪明的迭代器或 Kotlin 语法可以使其更加优雅。

在下面的 Java 中,我们能够通过将主索引 i 嵌入到 for 循环中来简洁地捕获整个迭代,并且仅涉及隐式增量操作,这可能是计算效率较高的(与除法相比)和模)...

public static void main(String[] args) {
    int nrow=1000, ncol=1000;
    int size=nrow*ncol;
    double[] data = new double[size];

    for (int i=0, r = 0; r < nrow; r++) {
        for (int c = 0; c < ncol; c++,i++) {
            data[i]= r*c;
        }
    }
}

在 Kotlin 中,如下所示,我找到了一个解决方案,其中索引 i 被强制具有循环 block 之外的范围。此外,i++ 行在某种程度上被隐藏并与循环结构分离。在这种情况下,我缺少优雅的 Kotlin 语法,例如“构建器”、没有分号等。我谦虚地认为这是因为 Kotlin 中的 for 循环流控制结构的表达能力较差。诚然,这并不重要,但更多的是令人失望。

fun main(args : Array<String>) {
    val nrow = 1000
    val ncol = 1000
    val size = nrow * ncol
    val data = DoubleArray(size)

    var i = 0
    for(r in 0 until nrow) {
        for(c in 0 until ncol) {
            data[i] = (r * c).toDouble()
            i++
        }
    }
}

最佳答案

简单的方法

您可以根据偏移量计算索引...

fun main(args : Array<String>) {
    val nrow = 1000
    val ncol = 1000
    val size = nrow * ncol
    val data = DoubleArray(size)

    for(r in 0 until nrow) {
        for(c in 0 until ncol) {
            data[(ncol*r) + c] = (r * c).toDouble()
        }
    }
}

包装方式

您可以包装数组,简化访问...

class ArrayWrapper<T>(val height: Int, val width: Int, val default: Int) {
    private val data: Array<Any?> = Array(height, {default})
    operator fun get(x: Int, y: Int) = data[(width * y) + x] as T
    operator fun set(x: Int, y: Int, value: T) {
        data[(width * y) + x] = value
    }

    val rowIndices = (0 until width)
    val columnIndices = (0 until height)
}

fun main(args : Array<String>) {
    val nrow = 1000
    val ncol = 1000
    val data = ArrayWrapper<Double>(nrow, ncol, 0)

    for(r in data.rowIndices) {
        for(c in data.columnIndices) {
            data[r, c] = (r * c).toDouble()
        }
    }
}

关于arrays - 在 Kotlin 中使用嵌套 for 循环导航多维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49388031/

相关文章:

javascript - 使用 java 或 google script 读取单元格值

batch-file - 使用 Plink 使用加密密码通过 SSH 连接到多个服务器

c++ - 让基于范围的 for 循环从 vector 中的点开始

javascript - 我不明白数组是如何工作的

python - 声明大小未知的 2D numpy 数组

arrays - 如何在 Swift 3 多维数组中获取垂直切片?

java - 从文件读入数组

java - 由于 Integer.parseInt 而崩溃

javascript - 创建不同行为的数组数组

python - NumPy 多维数组迭代如何工作? (有无 nditer)