F#jagged数组赋值

onl*_*com 2 f# jagged-arrays

我得到了奇怪的行为 - 当我将单个值分配给锯齿状数组时,它会更改整个列的值.

let testArray = Array.create 5 (Array.create 5 nan)
testArray.[3].[3] <- 1.0
Run Code Online (Sandbox Code Playgroud)

上面的代码不是更改单个单元格的值,而是更改整个列的值.

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|]|]
Run Code Online (Sandbox Code Playgroud)

Fyo*_*kin 13

发生这种情况是因为你没有创建一个二维数组(正如我所想的那样),而是你正在创建两个数组:一个数组中有5个数组nan,另一个数组有5个引用第一个数组它.为了说明这个问题,以下代码完全等同于您的代码:

let firstArray = Array.create 5 nan
let testArray = Array.create 5 firstArray
testArray.[3].[3] <- 1.0
Run Code Online (Sandbox Code Playgroud)

因此,该行testArray.[3].[3] <- 1.0实际上只更改了一个元素 - 第四个元素firstArray,但如果您然后尝试打印出来testArray,那么相同的元素会多次显示,因为有多个引用firstArray.

如果你想创建一个包含五个不同数组的数组,你需要使用Array.init,而不是该元素采用"创建下一个元素"函数:

let testArray = Array.init 5 (fun _ -> Array.create 5 nan)
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用list comprehension来创建数组:

let testArray = [|for i in 1..5 -> Array.create 5 nan|]
Run Code Online (Sandbox Code Playgroud)

两者都会给你相同的结果,不过第一个会有更好的表现.

如果您确实需要使用二维数组(而不是数组数组),您可能需要查看Array2D:

let testArray = Array2D.create 5 5 nan
testArray.[3,3] <- 1.0
Run Code Online (Sandbox Code Playgroud)