是否可以在F#中对Array2D进行切片?
说,
let tmp =Array2D.init 100 100 (fun x y -> x * 100 + y)
如何从tmp
tmp.[0,1..]
中检索某些列或某些行?
答案 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)