Многомерные массивы в Swift
Изменение: Как указывает Адам Вашингтон, начиная с бета-версии 6, этот код работает как есть, поэтому вопрос больше не актуален.
Я пытаюсь создать и перебрать двумерный массив:
var array = Array(count:NumColumns, repeatedValue:Array(count:NumRows, repeatedValue:Double()))
array[0][0] = 1
array[1][0] = 2
array[2][0] = 3
array[0][1] = 4
array[1][1] = 5
array[2][1] = 6
array[0][2] = 7
array[1][2] = 8
array[2][2] = 9
for column in 0...2 {
for row in 0...2 {
println("column: \(column) row: \(row) value:\(array[column][row])")
}
}
Тем не менее, это вывод, который я получаю:
column: 0 row: 0 value:3.0
column: 0 row: 1 value:6.0
column: 0 row: 2 value:9.0
column: 1 row: 0 value:3.0
column: 1 row: 1 value:6.0
column: 1 row: 2 value:9.0
column: 2 row: 0 value:3.0
column: 2 row: 1 value:6.0
column: 2 row: 2 value:9.0
Похоже, что последний столбец в строке перезаписывает значения других столбцов.
Я объявляю это неправильно?
Изменение: Возможно, картина с игровой площадки поможет:
![Captured from Playground]()
Ответы
Ответ 1
Для будущих читателей вот элегантное решение (5х5):
var matrix = [[Int]](repeating: [Int](repeating: 0, count: 5), count: 5)
и динамический подход:
var matrix = [[Int]]() // creates an empty matrix
var row = [Int]() // fill this row
matrix.append(row) // add this row
Ответ 2
Как указано в других ответах, вы добавляете один и тот же массив строк в каждый столбец. Чтобы создать многомерный массив, вы должны использовать цикл
var NumColumns = 27
var NumRows = 52
var array = Array<Array<Double>>()
for column in 0..NumColumns {
array.append(Array(count:NumRows, repeatedValue:Double()))
}
Ответ 3
var array: Int[][] = [[1,2,3],[4,5,6],[7,8,9]]
for first in array {
for second in first {
println("value \(second)")
}
}
Чтобы добиться того, что вы ищете, вам нужно инициализировать массив до правильного шаблона, а затем цикл, чтобы добавить массивы строк и столбцов:
var NumColumns = 27
var NumRows = 52
var array = Array<Array<Int>>()
var value = 1
for column in 0..NumColumns {
var columnArray = Array<Int>()
for row in 0..NumRows {
columnArray.append(value++)
}
array.append(columnArray)
}
println("array \(array)")
Ответ 4
Возможно, ваша проблема связана с недостатком более ранней версии Swift или бета-версии Xcode. Работая с версией Xcode 6.0 (6A279r) 21 августа 2014 года, ваш код работает, как и ожидалось, с таким выводом:
column: 0 row: 0 value:1.0
column: 0 row: 1 value:4.0
column: 0 row: 2 value:7.0
column: 1 row: 0 value:2.0
column: 1 row: 1 value:5.0
column: 1 row: 2 value:8.0
column: 2 row: 0 value:3.0
column: 2 row: 1 value:6.0
column: 2 row: 2 value:9.0
Я просто скопировал и вставил ваш код в игровую площадку Swift и определил две константы:
let NumColumns = 3, NumRows = 3
Ответ 5
Используя http://blog.trolieb.com/trouble-multidimensional-arrays-swift/ в качестве старта, я добавил дженерики к моим:
class Array2DTyped<T>{
var cols:Int, rows:Int
var matrix:[T]
init(cols:Int, rows:Int, defaultValue:T){
self.cols = cols
self.rows = rows
matrix = Array(count:cols*rows,repeatedValue:defaultValue)
}
subscript(col:Int, row:Int) -> T {
get{
return matrix[cols * row + col]
}
set{
matrix[cols * row + col] = newValue
}
}
func colCount() -> Int {
return self.cols
}
func rowCount() -> Int {
return self.rows
}
}
Ответ 6
Вы создаете массив из трех элементов и присваиваете все три одинаковой вещи, которая сама представляет собой массив из трех элементов (три пары).
Когда вы вносите изменения, вы изменяете поплавки во внутреннем массиве.
Ответ 7
Ваша оригинальная логика для создания матрицы действительно правильная, и она даже работает в Swift 2. Проблема в том, что в цикле печати переменные строки и столбца меняются на противоположные. Если вы измените его на:
for row in 0...2 {
for column in 0...2 {
print("column: \(column) row: \(row) value:\(array[column][row])")
}
}
вы получите правильные результаты. Надеюсь, это поможет!