F#Array2D切片

时间:2010-03-02 21:26:51

标签: f#

是否可以在F#中对Array2D进行切片? 说, let tmp =Array2D.init 100 100 (fun x y -> x * 100 + y)

如何从tmp tmp.[0,1..]中检索某些列或某些行?

5 个答案:

答案 0 :(得分:8)

从2D数组中提取1D部分时,我觉得使用Seq.Cast<T>很方便。它以左右/上下顺序从2D数组中生成元素。

像这样:

let A = array2D [[1;2;3];[4;5;6];[7;8;9]]

let flatten (A:'a[,]) = A |> Seq.cast<'a>

let getColumn c (A:_[,]) =
    flatten A.[*,c..c] |> Seq.toArray

let getRow r (A:_[,]) =
    flatten A.[r..r,*] |> Seq.toArray  

FSI的一个例子:

> flatten A;;
val it : seq<int> = seq [1; 2; 3; 4; ...]
> getRow 2 A;;
val it : int array = [|7; 8; 9|]
> getColumn 0 A;;
val it : int array = [|1; 4; 7|]

答案 1 :(得分:6)

是。抓取2D块很容易:

tmp.[10..20,30..40]

但是,如果你想要一维切片,我相信你需要将它从2D切片中投射出来

tmp.[0..0,1..] |> fun arr -> Array.init 99 (fun i -> arr.[0,i])

答案 2 :(得分:4)

是的,你可以试试这个tmp.[0..0, 1..]

let tmp = Array2D.init 100 100 (fun x y -> x * 100 + y)
printf "%A" tmp.[1..2, ..3]

[[100; 101; 102; 103]
 [200; 201; 202; 203]]

如果您只需要一行或一列,则必须重复该数字。

[1..1, 2..3]
[1..2, 2..2]

如果您想要在离开号码之前或之后。

[1.., 2..3]
[..2, 2..2]

数组切片始终返回相同的顺序数组。

> tmp.[1..1, 2..2]
val it : int [,] = [[102]]

> tmp.[1..1, 2..2].[0, 0]
val it : int = 102

答案 3 :(得分:4)

您自己提供了答案。

您问题中的示例代码将准确提供您想要的内容。 我稍微改变了它,以便更好地证明它有效。

let tmp = Array2D.init 10 10 (fun x y -> sprintf "%d,%d" x y)
//3rd row
let row3 = tmp.[2,0..]
//2nd column
let col2 = tmp.[0..,1]
;;

这里的关键是对行或列使用单个值。然后它会为您提供一个切片作为一维数组。如果您对行和列都使用范围,那么您将得到一个Array2D类型的片段。

编辑:适用于Visual F#3.1.1,旧版本未经测试。

答案 4 :(得分:4)

在F#3.1中你可以这样做:

// Get row 3 from a matrix as a vector:
matrix.[3, *]

// Get column 3 from a matrix as a vector:
matrix.[*, 3]

(见https://msdn.microsoft.com/en-us/library/dd233214.aspx?f=255&MSPPError=-2147217396