0

我之前在 c# 中在这里问过这个问题,但实际上并没有一种简洁的方式来做到这一点。我现在正尝试在 fsharp 中做同样的事情,看看情况如何。

我有两个长度和类型相同的数组,我想将它们组合成一个长度和 2 列的数组。我有这样的代码:

let twoDimensionalArray (arr1:array<'a>) (arr2:array<'a>) = 
    let rws = arr1|> Array.length
    Array2D.init rws 1 (fun i j -> arr1.[i], arr2.[i]) 

老实说,这让我有点惊讶,因为我认为列维度中应该有一个 2,如下所示:

Array2D.init rws 2 (fun i j -> arr1.[i], arr2.[i]) 

但是如果我将其更改为 2,那么我会得到:

val it : (float * float) [,] = [[(1.0, 3.0); (1.0, 3.0)]
                            [(2.0, 4.0); (2.0, 4.0)]]

对于这个数据:

let arr1 = [| 1.0; 2.0 |]
let arr2=  [|3.0; 4.0 |]

为什么?

另外,我真的很想写得更笼统,所以如果第一个数组有 2 列,第二个有 1 列,我会得到一个 3 列矩阵,依此类推。我试过这个:

let MultiArray (arr1:array<'a>) (arr2:array<'a>)  = 
    let rws = arr1.Length
    let c1 = arr1.GetLength(1)
    let c2 = arr2.GetLength(1)
    let cols = c1+c2
    Array2D.init rws cols (fun i j -> arr1.[i], arr2.[i]) 

但这是有缺陷的。

你能告诉我我该怎么做吗?还有为什么我的第一个功能有效但我认为是错误的?

谢谢

谢谢约翰!工作解决方案:

let MultiArray (inp:float[][]) =
    let cls = inp |> Array.length
    let rows = inp.[0] |> Array.length
    Array2D.init rows cls (fun i j -> inp.[j].[i])

样本数据和使用:

let arr1 = [|1.0 ; 4.0; 6.0;5.;8.|] 
let arr2= [|7.0; 8.0; 9.0;9.;10. |] 
let inp = [| arr1; arr2; arr1|]

MultiArray inp;;
val it : float [,] = [[1.0; 7.0; 1.0]
                  [4.0; 8.0; 4.0]
                  [6.0; 9.0; 6.0]
                  [5.0; 9.0; 5.0]
                  [8.0; 10.0; 8.0]]
4

2 回答 2

3

因此,第一个代码出现意外版本的原因是您正在创建一个 2D 元组数组 - 而不是一个 2D 值数组。在这种情况下,您实际上应该将第一个维度的大小设置为 1,因为第二个维度隐藏在元组具有更多变量的事实中。

一个创建实际二维数组的简单版本是

Array2D.init rws 2 (fun i j ->match j with |0 -> arr1.[i] |1 -> arr2.[i]) 

更通用的版本会像这样将数组数组作为输入

let MultiArray (inp:float[][])
    let count = inp |> Array.length
    let rows = inp.[0] |> Array.length
    Array2D.init count rows (fun i j -> inp.[j].[i]
于 2013-10-08T09:36:10.500 回答
-1

不错的解决方案;建议将此行更改为:

let c1 = arr1.GetLength(0)
let c2 = arr2.GetLength(0)

就我而言,如上所述,我得到的索引超出了 1 的范围。

但是我也更喜欢“通用”:

Array2D.init count rows (fun i j -> inp.[j].[i])
于 2018-11-27T18:05:29.830 回答