F# 如何将二维数组转换为F中的列表列表#
我有一个二维浮点数数组:F# 如何将二维数组转换为F中的列表列表#,f#,F#,我有一个二维浮点数数组: let scores = Array2D.init<float> width height (fun _ _ -> 0.) 将成为: [ [1, 2, 3] [4, 5, 6] [7, 8, 9] ] 我发现这个问题: 但是它将2d数组转换成一个列表,我试图找到如何将它转换成一个列表列表。 我可以遍历元素并构建列表,但我确信一定有更好的方法。这是由F的切片运算符(现在也是C 8)所提供的可读性很强的方法。 要切片多维数组,可以使用[范
let scores = Array2D.init<float> width height (fun _ _ -> 0.)
将成为:
[
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
]
我发现这个问题:
但是它将2d数组转换成一个列表,我试图找到如何将它转换成一个列表列表。
我可以遍历元素并构建列表,但我确信一定有更好的方法。这是由F的切片运算符(现在也是C 8)所提供的可读性很强的方法。 要切片多维数组,可以使用
[范围,范围]
例如,[*,n]
用于第n列,而[n,*]
用于第n行
我们需要的最后一个部分是数组的高度,即维0,由
array.GetLength 0
现在,使用列表理解对2D数组进行切片变得很简单
[
let height = arr.GetLength 0
for row in 0..height-1 do
yield arr.[row,*] |> List.ofArray
]
对于Henrik Hansen建议的非零索引数组,最好使用:
[
for i in arr.GetLowerBound(0)..arr.GetUpperBound(0)
do yield arr.[i,*] |> List.ofArray
]
测试
let counter = ref 0
//generate the test array
let arr = Array2D.init (3) (3) (fun _ _ -> Interlocked.Increment(counter))
arr |> printfn "%A"
let lists =
[
let height = arr.GetLength 0
for row in 0..height - 1 do
yield arr.[row,*] |> List.ofArray
]
lists |> printfn "%A"
输出:
[[1; 2; 3]
[4; 5; 6]
[7; 8; 9]]
[[1; 2; 3]; [4; 5; 6]; [7; 8; 9]]
另一种基于Asti想法的方法:
module Array2D =
let toListOfLists (arr2d: 'a [,]) = [ yield! [arr2d.GetLowerBound(0)..arr2d.GetUpperBound(0)] |> List.map (fun i -> arr2d.[i,*] |> List.ofArray) ]
let base002D = Array2D.init 5 5 (fun x y -> (x, y))
let base152D = Array2D.initBased 1 5 5 5 (fun x y -> (x, y))
printfn "%A" (base002D |> Array2D.toListOfLists)
printfn "%A" (base152D |> Array2D.toListOfLists)
它适用于不同的基。当第二维度的基索引不是0时,从开始到结束的切片范围
*
是否仍然有效?@kaefer它确实尊重下限。使用单个列表理解可能更简单<代码>[对于arr2d.GetLowerBound(0)…arr2d.GetUpperBound(0)中的i,不产生arr2d。[i,*]|>List.of数组]@Asti:是的,也可以。重要的是,我们必须使用上界和下界,使它能够处理除零以外的基。绝对。尽管非零索引数组相对较少,而且大多数编写的数组代码通常假定零索引。
module Array2D =
let toListOfLists (arr2d: 'a [,]) = [ yield! [arr2d.GetLowerBound(0)..arr2d.GetUpperBound(0)] |> List.map (fun i -> arr2d.[i,*] |> List.ofArray) ]
let base002D = Array2D.init 5 5 (fun x y -> (x, y))
let base152D = Array2D.initBased 1 5 5 5 (fun x y -> (x, y))
printfn "%A" (base002D |> Array2D.toListOfLists)
printfn "%A" (base152D |> Array2D.toListOfLists)