如何通过将每一行附加到上面的行来将二维数组展平为一维数组?
我的问题是不明白如何使用 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)
Run Code Online (Sandbox Code Playgroud)
我将如何使用 map 以便将 map 的返回类型更改为一维数组?
如果你只是想压平它,你可以将它转换为 seq:
colors |> Seq.cast<Color>
|> Seq.length //val it : int = 384000
Run Code Online (Sandbox Code Playgroud)
Array2D 中可能有更方便的东西,但 Array2D 实际上是一个 .NET 集合。您可以使用不规则数组或列表,然后可以访问Seq.concat
或collect
。
添加1
这里它已经在一维列表中:
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]
Run Code Online (Sandbox Code Playgroud)
具有活跃模式
根据实际的复杂性,这也可能是活动模式的良好候选者。下面定义了黑色和红色的主动识别器以及模式匹配,然后生成 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
Run Code Online (Sandbox Code Playgroud)