2011-05-22 38 views

回答

1

我建议您不要在2D阵列中使用数组阵列,主要有三个原因。首先,它允许不一致:不是所有列(或行,请选择)都需要具有相同的大小。其次,效率低下 - 你必须遵循两个指针而不是一个指针。第三,存在很少的库函数,这些函数透明且有效地用作二维数组的数组。

考虑到这些事情,您应该使用支持2D阵列的库,例如scalala,或者您应该自己写。如果你做后者,除其他外,这个问题神奇地消失。

所以就优雅而言:不,没有办法。但除此之外,你开始的路径包含地段不雅;你可能会尽最大努力迅速离开它。

+0

我完全相信,scala编译器神奇地将Array [Array]转换为真正的2D数组,因为它受标准库('Array.fill(n,dim,array)')支持。真是无赖。标准库中没有2D数组吗? (Vector [Vector [_]] ;-) – 2011-05-23 06:03:18

+0

“真正的二维数组”是什么意思? JVM不具有对多维数组的内置支持。 – 2015-12-26 16:48:19

+0

@SethTisue - 我假设一个“真正的二维数组”是一个M×N矩阵,大概是一个数据以行 - 主要顺序存储在内存中的地方,其中维是索引约定而不是单独的数据结构。或者,它可能是一个数组的数组,其维度被键入为相同的(如果您有一个类型化的大小参数,则正常数组不会)。关键属性是对于'a(i)(j)',索引'j'中的入/出界限不依赖于'i'。 (这是一个2D数组,例如C++。) – 2015-12-26 22:41:25

1

你只需要isDefinedAt检查索引i数组,如果它存在:

def do_to_elt(i:Int, j:Int): Unit = 
    if (a.isDefinedAt(i) && a(i).isDefinedAt(j)) f(a(i)(j)) 

编辑:错过关于优雅的解决方案的一部分,因为我的代码集中在错误的编辑前。

关于优雅:不,本身没有办法以更优雅的方式表达它。有些人可能会告诉你使用pimp-my-library -Pattern使它看起来更优雅,但实际上它不在这种情况下。

如果您的唯一用例是在索引有效时使用多维数组的元素执行函数,那么此代码会执行该操作,您应该使用它。你可以通过改变签名概括的方法取功能应用到元素,也许值,如果索引无效这样的:

def do_to_elt[A](i: Int, j: Int)(f: Int => A, g: => A =()) = 
    if (a.isDefinedAt(i) && a(i).isDefinedAt(j)) f(a(i)(j)) else g 

,但我不会改变任何事情不止于此。这看起来并不更优雅,但却拓宽了用例。

(另外:如果您在使用数组时,你主要做性能方面的原因而在这种情况下,它甚至可能会更好,不使用isDefinedAt但进行基于阵列的长度有效性检查。)

+0

是的,这就是我所做的。我希望有更优雅的东西。 – 2011-05-22 21:55:59