Многомерные массивы в 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])")

  }
}

вы получите правильные результаты. Надеюсь, это поможет!