集合的尺寸,以及如何以高效,优雅的方式遍历它

时间:2011-01-10 17:06:53

标签: scala multidimensional-array

我正试图找到一种优雅的方式来处理Scala中的多维集合。我的理解是,我可以使用制表来获得最多5维的集合,例如在以下二维数组的情况下:

val test = Array.tabulate[Double](row,col)(_+_)

我可以使用

访问数组的元素
    for(i<-0 until row) {
       for(j<-0 until col) {
         test(i)(j) = 0.0
       }
    }

如果我不知道我将要处理的事情,那么可能是一种简洁的方法来确定集合的结构并跨越它,而不会做类似的事情:

    case(Array(x)) =>
       for(i<-1 until dim1) {
          test(i) = 0.0
       }

    case(Array(x,y)) =>
       for(i<-1 until dim1) {
          for(j<-1 until dim2) {
              test(i)(j) = 0.0
          }
       }

    case(Array(x,y,z)) =>
    ...

维度值n1,n2,n3等是私有的,对吗?另外,如果我想要一个案例来处理遍历,那么在处理n维对象时,是否会使用相同的技巧将2-D数组展开为1-D向量?

提前致谢

布鲁斯

2 个答案:

答案 0 :(得分:4)

在这种情况下我会使用递归和模式匹配:

def doSome(a:Array[_]){ 
   for(i <- a){ 
      i match{ 
         case x:Array[_] => doSome(x) 
         case x => println(x) // do something sensible here
      } 
   } 
}

答案 1 :(得分:1)

首先,一些更正:

val test = Array.tabulate[Double](row,col)(_+_)

这将生成Array[Array[Double]],并且将每个元素归零的最简单方法是:

test foreach { inner => in.indices foreach { _ => 0.0 } }

循环遍历外部数组包含的每个内部数组,并为内部数组更新每个元素。没有必要知道元素的实际数量,也不需要这样做(想象一下用并行数组做的那样!)

更容易使用map,并且使用数组就好像它是不可变的,但这似乎违背了原始请求的精神,所以快速移动上...

还误解了从制表函数返回的多维数组的性质(例如嵌套的数组数组)。您也使用模式匹配,就好像它是Java switch语句一样,这不太对。要匹配不同维度的数组,你需要这样的东西:

case Array[Double] => ...
case Array[Array[Double]] => ...

但我建议反对这种做法。在类型系统中安全表达并不容易,并且您已经确切地知道根据您提供的参数数量从表格中返回的类型