Размеры коллекции и как пройти ее эффективно и элегантно - PullRequest
1 голос
/ 10 января 2011

Я пытаюсь найти элегантный способ работы с многомерными коллекциями в Scala.Насколько я понимаю, я могу иметь до 5-мерной коллекции с использованием таблиц, например, в случае следующего 2-мерного массива:

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 ]

4 голосов
/ 10 января 2011

я бы использовал рекурсию и сопоставление с образцом в этом случае:

def doSome(a:Array[_]){ 
   for(i <- a){ 
      i match{ 
         case x:Array[_] => doSome(x) 
         case x => println(x) // do something sensible here
      } 
   } 
}
1 голос
/ 11 января 2011

Во-первых, некоторые исправления:

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

Это даст Array[Array[Double]], и самый простой способ обнулить каждый элемент:

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

Где вы перебираете все внутренниемассив содержится во внешнем массиве, а для внутреннего массива обновите каждый элемент.Не нужно знать фактическое количество элементов, и при этом это нежелательно (просто представьте, что вы делаете это с параллельным массивом!)

Было бы намного проще в использовании map и работайте с массивом, как если бы он был неизменным, но это, кажется, идет вразрез с духом вашего первоначального запроса, поэтому быстро движется дальше ...

А также неправильно понимает природу многомерных массивоввозвращается из функции табулирования (например, вложенный массив массивов).Вы также используете сопоставление с образцом, как если бы это был оператор переключения Java, это не совсем верно.Чтобы сопоставить массивы различной размерности, вам нужно что-то вроде этого:

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

Но я бы посоветовал против такого подхода.Было бы нелегко безопасно выразить в системе типов, и вы уже точно знаете, какой тип был возвращен из таблицы, исходя из количества аргументов, которые вы указали

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...