Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

f# flattening a 2d array to 1d array

Tags:

f#

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?

like image 892
Grayden Hormes Avatar asked Oct 26 '16 05:10

Grayden Hormes


People also ask

What does ⟨F⟩ mean?

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.

What does the letter F mean in math?

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 ).

What does F stand for in the Etruscan alphabet?

In the Etruscan alphabet, 'F' probably represented /w/, as in Greek, and the Etruscans formed the digraph 'FH' to represent /f/.

Is the letter F doubled at the end of words?

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.


2 Answers

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]
like image 88
Ilya Kharlamov Avatar answered Sep 28 '22 14:09

Ilya Kharlamov


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
like image 31
s952163 Avatar answered Sep 28 '22 15:09

s952163