2016-11-14 145 views
2

我越來越奇怪的行爲 - 當我將一個單獨的值賦給鋸齒陣列時,它會更改整列的值。F#鋸齒陣列分配

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

[Array.create和鋸齒狀排列]的可能的複製( 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