How to make Seq.unzip

I have foo: seq<int*int>

I want to break up beaten items and then save the results in two variables, each of which is seq<int>

I was wondering if there was a nicer way to do this, for example.

 let item1, item2 = foo |> ????? 

My current solution:

 let item1 = foo |> Seq.map(fun (f1,_) -> f1) let item2 = foo |> Seq.map(fun (_,f2) -> f2) 
+5
source share
4 answers

Unfortunately, there is no drop-in Seq.unzip included in the language, although there are equivalents for lists ( List.unzip ) and arrays ( Array.unzip ).

There are several ways to define such a function, one of which is:

 let unzip sequence = let (lstA, lstB) = Seq.foldBack (fun (a,b) (accA, accB) -> a::accA, b::accB) sequence ([],[]) (Seq.ofList lstA, Seq.ofList lstB) 

Alternatively, if you do not need to switch between the list, you can simply:

 let item1, item2 = let it1, it2 = foo |> List.ofSeq |> List.unzip (Seq.ofList it1, Seq.ofList it2) 
+6
source

What you want to get is two different sequences, so you will not find a much more beautiful way to do this. What you have is almost enough, but you can make it a little shorter by using fst and snd to fake the first and second elements of the tuples, respectively, and write both expressions on the same line:

 let items1, items2 = foo |> Seq.map fst, foo |> Seq.map snd 
+3
source

For lists and arrays, these functions are built-in:

 > [(1, "foo"); (2, "bar"); (3, "baz")] |> List.unzip;; val it : int list * string list = ([1; 2; 3], ["foo"; "bar"; "baz"]) > [|(1, "foo"); (2, "bar"); (3, "baz")|] |> Array.unzip;; val it : int [] * string [] = ([|1; 2; 3|], [|"foo"; "bar"; "baz"|]) 

This does not exist for Seq .

+3
source

To add TheInnerLight's answer, the official documentation tells us that:

Seq.zip and Seq.zip3 take two or three sequences and produce a sequence of tuples. These functions are similar to the corresponding functions available for lists. There is no corresponding functionality for splitting one sequence into two or more sequences. If you need this functionality for a sequence, convert it to a list and use List.unzip .

My spontaneous solution (similar to the OP approach) would be to write:

 let unzip sequence = let source = Seq.cache sequence Seq.map fst source, Seq.map snd source 

(I tested it in FSI for 1,000,000 items, and it is also a bit slower than the List.unzip method on my computeur)

+2
source

All Articles