F # Array2D slices

Is it possible to cut Array2D in F #? to tell, let tmp =Array2D.init 100 100 (fun x y -> x * 100 + y)

how to get some columns or some rows from tmphow tmp.[0,1..]?

+3
source share
5 answers

Yes. Easy to capture two-dimensional pieces:

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

However, if you want a 1D fragment, I think you need to project it from a 2D fragment

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

When extracting 1D partitions from 2D arrays, I find it convenient to use Seq.Cast<T>. This gives elements from a 2D array in left-right / top-bottom order.

Like this:

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  

And an example in 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|]
+8
source

, 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
+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]
;;

The key value here is to use a single value for a row or column. Then it gives you a slice as a 1D array. If you use ranges for rows and columns, you get a fragment of type Array2D.

Edit: Works on Visual F # 3.1.1, older versions are not tested.

+4
source

In F # 3.1 you can do this:

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

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

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

+4
source

Source: https://habr.com/ru/post/1735125/


All Articles