Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# take a list, return list of tuples

Tags:

list

tuples

f#

I've done some research and I see that the List.zip function takes two lists and returns one list of tuples, but how do you change one list into a list of tuples?

let rec combinePair xs =
    match xs with
    | [] -> []
    | [x1] -> []
    | x1::x2::x3::xs -> [(x1, x2)]
    | x1::x2::xs -> [(x1, x2)] 

If an odd number of elements exist in the list, the last element should be dropped, if an even number of elements exist they should be returned as a list of tuples. For example

combinePair [x1; x2; x3; x4] = [(x1, x2); (x3, x4)]
like image 783
jynx678 Avatar asked Mar 10 '23 20:03

jynx678


2 Answers

Your code is almost there.

Here's the thinking:

  • when given an empty list, the result is an empty list (you already got that).
  • when given a list of one element, the result is an empty list (got that too).
  • otherwise, the first item of result is a tuple composed of the first two elements, and the rest of result is the result of applying the same process to the rest of the input.

This can be almost identically translated to F#:

let rec combinePair xs =
    match xs with
    | [] | [_] -> []
    | x1::x2::rest -> (x1, x2) :: (combinePair rest)

(note how I combined the first two cases on one line, [] | [_] ->)

like image 199
Fyodor Soikin Avatar answered Mar 15 '23 13:03

Fyodor Soikin


I'm sure there are prettier solutions but for those who are allergic to recursion:

let xsOdd =  [1;2;3;4;5]

List.chunkBySize 2 xsOdd 
    |> List.filter (fun x -> x.Length = 2) 
    |> List.map (fun x -> x.[0],x.[1])
//val it : (int * int) list = [(1, 2); (3, 4)]
like image 38
s952163 Avatar answered Mar 15 '23 13:03

s952163