f#中的Concat 2D数组

nik*_*nik 5 f#

如何组合两个2d阵列呢?

我的假设(我可以很容易地测试这个)是他们总是有相同数量的列:

let concatArrays (arr1:obj[,]) (arr2:obj[,]) = 
    ([arr1; arr2]) |> Array2d.concat
Run Code Online (Sandbox Code Playgroud)

但这个功能并不存在.为了清楚起见,结果应该产生一个2d数组,其长度=长度和与原始数组2D相同的列数,并且应该与输入的类型相同,这里是obj [,].我显然可以在循环结构中执行此操作,但我想知道f#方式.谢谢.

我试过这个:

let append2D (arr1:float[,]) (arr2:float[,]) = 
    let cls = arr1.GetLength 1
    let rows1 = arr1.GetLength 0
    let rows2 = arr2.GetLength 0
    Array2D.init (rows1+rows2) cls (fun i j -> match i with | a when a <= rows1 -> arr1.[i,j] | _ ->  arr2.[i,j])
Run Code Online (Sandbox Code Playgroud)

但这回来时索引越界错误.

最后一行更新:

 Array2D.init (rows1+rows2) cls (fun i j -> if i < rows1 then arr1.[i,j] else arr2.[i,j])  
Run Code Online (Sandbox Code Playgroud)

更新工作方案:

 Array2D.init (rows1+rows2) cls (fun i j -> if i < rows1 then arr1.[i,j] else arr2.[i-rows1,j])  
Run Code Online (Sandbox Code Playgroud)

谢谢大家

Gen*_*ski 6

遵循此建议,此处是任意类型的concat两个相等列大小Array2D参数的函数'a:

let concat (a1: 'a[,]) (a2: 'a[,]) =
    let a1l1,a1l2,a2l1,a2l2 = (Array2D.length1 a1),(Array2D.length2 a1),(Array2D.length1 a2),(Array2D.length2 a2)
    if a1l2 <> a2l2 then failwith "arrays have different column sizes"
    let result = Array2D.zeroCreate (a1l1 + a2l1) a1l2
    Array2D.blit a1 0 0 result 0 0 a1l1 a1l2
    Array2D.blit a2 0 0 result a1l1 0 a2l1 a2l2
    result
Run Code Online (Sandbox Code Playgroud)

您可以通过实验检验这一点,但它会比任何变种基于有时间更好的表现,Array2D.init因为Array2D.zeroCreateArray2D.blit实现高度优化.