Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# Array2D slices

Tags:

f#

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

how to retrieve some columns or some rows from tmp like tmp.[0,1..]?

like image 372
ahala Avatar asked Mar 02 '10 21:03

ahala


3 Answers

When extracting 1D sections from 2D arrays, I find it handy to use Seq.Cast<T>. It yields 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|]
like image 126
cfern Avatar answered Jan 30 '23 05:01

cfern


Yes. It's easy to grab 2D chunks:

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

However, if you want a 1D slice, I believe you'll need to project it out of a 2D slice

tmp.[0..0,1..] |> fun arr -> Array.init 99 (fun i -> arr.[0,i])
like image 36
kvb Avatar answered Jan 30 '23 04:01

kvb


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)

like image 26
Oenotria Avatar answered Jan 30 '23 04:01

Oenotria