How do you flatten a 2d array to a 1d array by appending each row to the one above?
My problem is not understanding how to use map to do this as other functional languages have a flatmap/(insert similar name here) function to do this.
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)
How woulds I use map such that the return type from the map is changed to a 1d array?
This sound is usually considered to be an allophone of /h/, which is pronounced in different ways depending upon its context; Japanese /h/ is pronounced as [ɸ] before /u/. In Welsh orthography, ⟨f⟩ represents /v/ while ⟨ff⟩ represents /f/. In Slavic languages, ⟨f⟩ is used primarily in words of foreign (Greek, Latin, or Germanic) origin.
In countries such as the United States, the letter "F" is defined as a failure in terms of academic evaluation. Other countries that use this system include Saudi Arabia, Venezuela, and the Netherlands. In the hexadecimal number system, the letter "F" or "f" is used to represent the hexadecimal digit fifteen (equivalent to 15 10 ).
In the Etruscan alphabet, 'F' probably represented /w/, as in Greek, and the Etruscans formed the digraph 'FH' to represent /f/.
It is often doubled at the end of words. Exceptionally, it represents the voiced labiodental fricative / v / in the common word "of". F is the twelfth least frequently used letter in the English language (after C, G, Y, P, B, V, K, J, X, Q, and Z ), with a frequency of about 2.23% in words.
for Sequences use 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;]
or even less typing with just Seq.reduce + Seq.append
seq2d |> Seq.reduce Seq.append
//[1; 2; 3; 4; 5; 6;]
for lists (but not Sequences) it's List.reduce + List.append
let list2d = [ [1;2;3]; [4;5] ]
list2d |> List.reduce List.append
//[1; 2; 3; 4; 5]
If you just want to flatten it you can cast it to a seq:
colors |> Seq.cast<Color>
|> Seq.length //val it : int = 384000
There might be something in Array2D that's more convenient but Array2D is really a .NET collection. You can work with ragged arrays or lists and then you can have access to Seq.concat
or collect
.
Add1
Here it is already in a 1D List:
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]
With Active Patterns
Depending on the actual complexity this might also be a good candidate for active patterns. Below an active recognizer for Black and Red is defined, together with the pattern matching, then the 2D List is generated which is fed to concat, and finally checked against the original Array2D. You don't need to work with Lists of course (e.g. can be seq for laziness or Array for performance).
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With