F # Array2D срезы - PullRequest
       15

F # Array2D срезы

4 голосов
/ 03 марта 2010

возможно ли нарезать Array2D в F #? сказать, let tmp =Array2D.init 100 100 (fun x y -> x * 100 + y)

как извлечь некоторые столбцы или строки из tmp, например tmp.[0,1..]?

Ответы [ 5 ]

8 голосов
/ 03 марта 2010

При извлечении одномерных секций из двумерных массивов я считаю удобным использовать Seq.Cast<T>. Выдает элементы из двумерного массива в порядке слева направо / сверху вниз.

Как это:

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|]
6 голосов
/ 03 марта 2010

Да. 2D-фрагменты легко получить:

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

Однако, если вы хотите 1D срез, я думаю, вам нужно спроецировать его из 2D среза

tmp.[0..0,1..] |> fun arr -> Array.init 99 (fun i -> arr.[0,i])
4 голосов
/ 16 августа 2015

В 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)

4 голосов
/ 15 августа 2014

Вы сами ответили.

Пример кода в вашем вопросе даст вам именно то, что вы хотите. Я немного изменил его, чтобы лучше показать, что он работает.

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 голосов
/ 03 марта 2010

Да, вы можете попробовать это 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...