将一个包含两个以上维度的java数组作为列表处理

时间:2012-06-15 20:36:44

标签: java groovy multidimensional-array mop

我正在使用Groovy编写一个DSL处理BASIC,我想在如何处理多个(超过2个)维数组方面提供一些帮助。

我正在处理这样的BASIC代码:

100 LET X = A(1, 2, 3)

处理一维情况很容易 - 只需创建一个返回A元素的闭包(通过MOP),而对于2维,我可以在表单中执行相同的操作

A(2, 3) == A.get(2)[3]

但是如何处理无限维数组呢?

更新:为了使这一点更清晰,问题是如何在DSL上下文中动态返回数组值?脚本解释器将A(1,2,3)视为函数调用,我可以使用MOP拦截它。但是如何在该上下文中返回数组元素的值?

2 个答案:

答案 0 :(得分:2)

如果你是一个用嵌套列表建模的n维数组(不是最节省内存的方法,但很容易实现),并希望访问索引[i_1, i_2, ... , i_n]的元素,你可以这样做:

def getElementAt(arr, ... indexes) {
    indexes.inject(arr) { a, ind -> a[ind] }
}

// A 2x2x3 array implemented with nested lists.
def arr = [[[1,1,1], [1,1,5]], [[1,1,1], [1,1,1]]]

// I want to get that 5!
assert getElementAt(arr, 0, 1, 2) == 5

// The line above is equivalent to:
assert arr[0][1][2] == 5

inject允许您迭代集合并从初始值开始累积给定操作的结果。在这种情况下,我们迭代我们想要从数组中获取的索引并使用整个数组开始迭代;然后,每次迭代返回给定索引处的子数组,该索引是将在下一次迭代中使用的值。如果您碰巧使用索引少于预期的索引,它将返回一个列表而不是一个整数,例如getElementAt(arr, 0, 1) == [1, 1, 5]

答案 1 :(得分:1)

最后我决定解析输入并使用它来通过MOP构建一个闭包:

    /* array references look like functions to Groovy so trap them */
    BinsicInterpreter.metaClass."$varName" = {Object[] arg ->
        def answer = "package binsic; $varName"
        arg.each { 
            answer = answer + "[$it]"
        }
        def something = shell.evaluate(answer)
        return something
    }

所以,如果我们有:

100 LET X = A(10, 20, 3)

MOP陷阱A(...)作为函数调用,上面的代码给了我A [10] [20] [3]