Reputation: 347
I am getting strange behavior - when I assign a single value to a jagged array, it changes values of the entire column.
let testArray = Array.create 5 (Array.create 5 nan)
testArray.[3].[3] <- 1.0
The code above, instead of changing the value of a single cell, changes the value of the entire column.
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|]|]
Upvotes: 2
Views: 715
Reputation: 80754
This happens because you're not creating a 2-dimensional array (as I assume you expect), but rather you're creating exactly two arrays: one array with 5 nan
s in it, and another array with 5 references to the first array in it. Just to illustrate the matter, the following code is completely equivalent to yours:
let firstArray = Array.create 5 nan
let testArray = Array.create 5 firstArray
testArray.[3].[3] <- 1.0
So that the line testArray.[3].[3] <- 1.0
actually changes only one element - the fourth one in firstArray
, but if you then try to print out testArray
, that same element shows up multiple times, because there are multiple references to firstArray
.
If you wanted to create an array with five different arrays in it, you need to use Array.init
, which instead of the element takes a "create next element" function:
let testArray = Array.init 5 (fun _ -> Array.create 5 nan)
Alternatively, you can use list comprehension to create the array:
let testArray = [|for i in 1..5 -> Array.create 5 nan|]
Both will give you the same result, though the first one will have slightly better performance.
If you really need to work with two-dimensional arrays (rather than arrays of arrays), you might want to look at Array2D
instead:
let testArray = Array2D.create 5 5 nan
testArray.[3,3] <- 1.0
Upvotes: 13