0

私は以前にここでc#でこの質問をしましたが、これを行う簡潔な方法は実際にはありませんでした。私は今 fsharp で同じことをしようとしていて、それがどうなるか見てみましょう。

長さとタイプが同じ 2 つの配列があり、それらを同じ長さと 2 列の 1 つに結合したいと考えています。私はこれを行うこのコードを持っています:

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 列で 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 に設定する必要があります。これは、タプルがより多くの変数を持っているという事実に 2 番目の次元が隠れているためです。

実際の 2D 配列を作成する単純なバージョンは次のようになります。

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 に答える