Как мне алгоритмически создавать и манипулировать многомерным массивом в Scala - PullRequest
3 голосов
/ 09 ноября 2011

Я пытаюсь написать программу для управления базой данных через Scala Gui, и у меня возникли большие проблемы с форматированием моих данных таким образом, чтобы они вводились в таблицу и заполнялись заголовки столбцов.Для этого мне сказали, что мне нужно будет использовать Array [Array [Any]] вместо ArrayBuffer [ArrayBuffer [String]], как я использую.

Моя проблема в том, как яя пытаюсь заполнить эти массивы модульно: я пытаюсь использовать одну и ту же функцию для рисования из разных таблиц в базе данных MySQL, каждая из которых имеет различное количество столбцов и записей.

Я смог(Я думаю) определить двумерный массив с

val Data = new Array[Array[String]](numColumns)(numRows)

, но я не нашел никаких способов редактирования отдельных ячеек в этом новом массиве.

Data(i)(j)=Value  //or
Data(i,j)=Value

не работают,и выдают мне ошибки об обновлении функциональности

Я уверен, что это не может быть так сложно, как я это делал, так каков простой способ управления этими вещами на этом языке?

Ответы [ 4 ]

5 голосов
/ 09 ноября 2011

Вам не нужно читать ваши данные в Array of Arrays - вам просто нужно преобразовать их в этот формат при подаче их в конструктор Table - что легко, как продемонстрировал мой ответ на ваш другой вопрос: Как настроить имена столбцов в таблице Scala?

Если вы создаете 2D-массив, вам нужна идиома

val data = Array.ofDim[String](numColumms, numRows)

(тамтакже new Array[String](numColumns, numRows), но это устарело.)

Вы получаете доступ к элементу (i, j) массива data с помощью data(i)(j) (помните, что они начинаются с 0).

Нов общем, вы должны избегать изменчивых коллекций (таких как Array, ArrayBuffer), если нет веской причины.Попробуйте Vector вместо этого.

Не зная формата, в котором вы извлекаете данные из базы данных, невозможно сказать, как поместить их в коллекцию.

Обновление :

В качестве альтернативы вы можете разместить информацию о типе слева, поэтому следующие условия эквивалентны (решите сами, какой вы предпочитаете):

val a: Array[Array[String]] = Array.ofDim(2,2)
val a = Array.ofDim[String](2,2)

Чтобы объяснить синтаксис для доступа / обновления элементов: asв Java многомерный массив - это просто массив массивов.Итак, a(i) - это элемент i элемента a, который равен Array[String], и, таким образом, a(i)(j) - элемент j этого массива, который является String.

.
3 голосов
/ 09 ноября 2011

Ответ Луиджи великолепен, но я хотел бы пролить свет на то, почему ваш код не работает.

val Data = new Array[Array[String]](numColumns)(numRows)

не делает то, что вы ожидаете. Часть new Array[Array[String]](numColumns) создает массив массивов строк с записями numColumns со всеми записями (массивами строк), равными NULL, и возвращает его. Следующий (numRows) затем просто вызывает функцию apply для этого возвращенного объекта, которая возвращает numRows -ую запись в этом списке, которая является нулевой.

Вы можете попробовать это в scala. REPL: Когда вы вводите

new Array[Array[String]](10)(9)

вы получите это как вывод:

res0: Array[String] = null

Решение Луиджи, вместо

Array.ofDim[String](2,2)

делает правильные вещи:

res1: Array[Array[String]] = Array(Array(null, null), Array(null, null))
1 голос
/ 10 ноября 2011

Ответ Луиджи великолепен, но я просто хотел указать на другой способ инициализации массива, который более идиоматичен / функционален - использование tabulate.Это берет функцию, которая принимает координаты ячейки массива в качестве входных данных и производит значение ячейки:

scala> Array.tabulate[String](4, 4) _
res0: (Int, Int) => String => Array[Array[String]] = <function1>

scala> val data = Array.tabulate(4, 4) {case (x, y) => x * y }
data: Array[Array[Int]] = Array(Array(0, 0, 0, 0), Array(0, 1, 2, 3), Array(0, 2, 4, 6), Array(0, 3, 6, 9))
1 голос
/ 09 ноября 2011

Это довольно уродливо, но вы можете обновить многомерный массив с помощью update

> val data = Array.ofDim[String](2,2)
data: Array[Array[String]] = Array(Array(null, null), Array(null, null))
> data(0).update(0, "foo")
> data
data: Array[Array[String]] = Array(Array(foo, null), Array(null, null))

Не уверен насчет эффективности этой техники.

...