2016-11-14 2 views
2

Я получаю странное поведение - когда я назначаю одиночное значение массиву с зубцами, он меняет значения всего столбца.F # назначение массива jagged

let testArray = Array.create 5 (Array.create 5 nan) 
testArray.[3].[3] <- 1.0 

Приведенный выше код вместо изменения значения одной ячейки изменяет значение всего столбца.

val it : float [] [] = 
    [|[|nan; nan; nan; 1.0; nan|]; [|nan; nan; nan; 1.0; nan|]; 
    [|nan; nan; nan; 1.0; nan|]; [|nan; nan; nan; 1.0; nan|]; 
    [|nan; nan; nan; 1.0; nan|]|] 
+2

Возможный дубликат [и зубчатыми-массив массива] (http://stackoverflow.com/questions/34252606/array-create-and-jagged-array) –

ответ

12

Это происходит потому, что вы не создаете 2-мерный массив (как я предполагаю, что вы ожидали), а вы создаете именно два массива: один массив с 5 nan с в ней, а другой массив с 5 ссылками на первый массив в нем. Просто, чтобы проиллюстрировать этот вопрос, следующий код полностью эквивалентен твоим:

let firstArray = Array.create 5 nan 
let testArray = Array.create 5 firstArray 
testArray.[3].[3] <- 1.0 

Так что линия testArray.[3].[3] <- 1.0 фактически изменяет только один элемент - четвертый в firstArray, но если вы попробуете распечатать testArray, что один и тот же элемент отображается несколько раз, потому что есть несколько ссылок на firstArray.

Если вы хотите создать массив с пятью различными массивами в нем, вам нужно использовать Array.init, что вместо элемента принимает «создать следующий элемент» функцию:

let testArray = Array.init 5 (fun _ -> Array.create 5 nan) 

В качестве альтернативы, вы можете использовать список для создания массива:

let testArray = [|for i in 1..5 -> Array.create 5 nan|] 

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

Если вам действительно нужно работать с двумерными массивами (а не массивы массивов), вы можете захотеть взглянуть на Array2D вместо:

let testArray = Array2D.create 5 5 nan 
testArray.[3,3] <- 1.0 
Смежные вопросы