f#将2d数组展平为1d数组

时间:2016-10-26 05:54:25

标签: f#

如何通过将每一行追加到上面的一行来将二维数组展平为一维数组?

我的问题是不了解如何使用map来执行此操作,因为其他函数语言具有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)

我如何使用map使地图中的返回类型更改为1d数组?

2 个答案:

答案 0 :(得分:2)

对于序列使用Seq.fold + Seq.append + empty Seq

let seq2d = seq {yield seq{1..3}; yield seq{4..6} }
seq2d |> Seq.fold Seq.append Seq.empty<int>
//[1; 2; 3; 4; 5; 6;]
只用Seq.reduce + Seq.append

打字甚至更少
seq2d |> Seq.reduce Seq.append
//[1; 2; 3; 4; 5; 6;]

对于列表(但不是序列),它是List.reduce + List.append

let list2d = [ [1;2;3]; [4;5] ]
list2d |> List.reduce List.append
//[1; 2; 3; 4; 5]

答案 1 :(得分:1)

如果您只想展平它,可以将其投射到seq:

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

Array2D中可能有一些比较方便的东西,但Array2D实际上是一个.NET集合。您可以使用不规则的数组或列表,然后就可以访问Seq.concatcollect

<强> ADD1

这里已经是一维名单:

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]

使用活动模式

根据实际的复杂程度,这也可能是active patterns的良好候选人。在下面定义了黑色和红色的主动识别器,以及模式匹配,然后生成2D列表,将其馈送到concat,最后检查原始的Array2D。当然,您不需要使用列表(例如,可以是seq用于懒惰或Array用于表现)。

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
相关问题