F # Array2D - Извлечение диагоналей - PullRequest
0 голосов
/ 27 февраля 2019

Допустим, у меня есть матрица

 [[0; 0; 1; 0; 0; 0]
  [0; 1; 0; 0; 0; 0]
  [2; 0; 0; 0; 0; 0]
  [0; 1; 0; 0; 0; 0]
  [0; 0; 1; 0; 0; 0]
  [0; 0; 0; 1; 0; 0]]

Я хочу извлечь диагонали в виде массива 1d, что означает [|2;1;1|] и [|2;1;1;1|]

Для строк и столбцов мы имеем

matrix.[i,*] // The ith row
matrix.[*,i] // the ith column

Можем ли мы построить нечто подобное для i-й диагонали в направлении вверх и вниз?

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Если вы не хотите использовать какую-либо внешнюю библиотеку, она не станет намного короче следующей:

let diag (mat: _ [,]) = 
    let l = min (mat.GetLength(0)) (mat.GetLength(1)) - 1
    [| for i in 0..l -> mat.[i,i] |]

Лично я не думаю, что это вообще проблема, но решать вам.Конечно, вы можете использовать Array.init или что-то еще вместо цикла for, но я бы предпочел заявленное решение.

0 голосов
/ 28 февраля 2019

Я не вижу, как предлагаемый синтаксис метода GetSlice будет применяться к вашему сценарию.С другой стороны, предоставление свойства индексатора Item может быть действительно полезным для извлечения диагоналей.

type 'a M = M of 'a list list with
    member me.Item i =
        let (M xss) = me in xss
        |> List.mapi (fun j ->
            List.mapi (fun k x ->
                if i = j - k then Some x else None )
            >> List.choose id )
        |> List.concat

Учитывая матрицу в виде списка списков:

let m =
 [[0; 0; 1; 0; 0; 0]
  [0; 1; 0; 0; 0; 0]
  [2; 0; 0; 0; 0; 0]
  [0; 1; 0; 0; 0; 0]
  [0; 0; 1; 0; 0; 0]
  [0; 0; 0; 1; 0; 0]]

M(m).[2] // val it : int list = [2; 1; 1; 1]
...