如何通过将每一行追加到上面的一行来将二维数组展平为一维数组?
我的问题是不了解如何使用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数组?
答案 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.concat
或collect
。
<强> 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