2016-10-26 2 views
2

Как вы выравниваете массив 2d в 1d-массив, добавляя каждую строку в одну выше?f # flattening 2d array to 1d array

Моя проблема не в том, чтобы понять, как использовать карту для этого, поскольку другие функциональные языки имеют функцию flatmap/(вставить подобное имя здесь) для этого.

let colors = Array2D.init 800 480 (fun i j -> 
    if i % 3 = 0 || j % 3 = 0 then Color.Black 
    else Color.Red) 
let data = colors |> map (fun c -> c) 

Как использовать карту таким образом, чтобы возвращаемый тип с карты был изменен на 1-й массив?

+2

Возможный дубликат [Array2D to Array] (http://stackoverflow.com/questions/12870368/array2d-to-array) –

ответ

2

Если вы просто хотите, чтобы сгладить его, вы можете бросить его в SEQ:

colors |> Seq.cast<Color> 
     |> Seq.length //val it : int = 384000 

Там может быть что-то в Array2D, что более удобно, но Array2D действительно коллекция .NET. Вы можете работать с оборванными массивами или списками, а затем вы можете получить доступ к Seq.concat или collect.

Add1

Здесь уже в списке 1D:

let colors = [for i in 0..799 do 
       for j in 0..479 -> 
       if (i % 3 = 0) || (j % 3 = 0) then Color.Black 
       else Color.Red] 

с активным Patterns

В зависимости от фактической сложности это также может быть хорошим кандидатом для active patterns , Ниже определяется активный распознаватель для черных и красных, а также сопоставление с образцом, затем генерируется 2D-лист, который подается на concat и, наконец, проверяется на исходный массив Array2D. Конечно, вам не нужно работать со списками (например, может быть seq для лености или массива для производительности).

let (|Black|Red|) input = if fst input % 3 = 0 || snd input % 3 = 0 then Black else Red 
let matchColor = 
    function 
    |Black -> Color.Black 
    |Red -> Color.Red 
let color3 = List.init 800 (fun i -> List.init 480 (fun j -> matchColor (i,j))) 

let color4 = color3 |> List.concat 
color4 |> Seq.length 

colors 
|> Array2D.mapi (fun i j x -> color3.[i].[j] = colors.[i,j]) 
|> Seq.cast<bool> 
|> Seq.filter not