Array.isDefinedAt用于scala中的n维数组

时间:2011-05-22 20:46:26

标签: arrays scala

是否有一种优雅的表达方式

val a = Array.fill(2,10) {1}
def do_to_elt(i:Int,j:Int) {
    if (a.isDefinedAt(i) && a(i).isDefinedAt(j)) f(a(i)(j))
}
scala中的

2 个答案:

答案 0 :(得分:1)

您只需检查索引i上的数组isDefinedAt是否存在:

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,而是根据数组的长度执行有效性检查。)

答案 1 :(得分:1)

我建议您不要将数组数组用于2D数组,原因主要有三个。首先,它允许不一致:并非所有列(或行,请选择)都需要相同的大小。其次,它是低效的 - 你必须遵循两个指针而不是一个。第三,很少有库函数可以作为2D数组在数组数组上透明有效地工作。

鉴于这些,您应该使用支持2D数组的库,例如scalala,或者您应该自己编写。如果你做了后者,除其他外,这个问题神奇地消失了。

所以在优雅方面:不,没有办法。但除此之外,你开始的路径包含很多的不雅;你最好快点离开它。