Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to merge two tuple seq with specified key gracefully?

Tags:

f#

I wrote the code but looks ugly.
Image there are two seqs like:

let x = [(1,"x");(2,"y")]
let y = [(1, "xx", "xxx");(2,"yy","yyy")]  

The elements are tuples but not the same shape.
The result need to be [(1, "x", "xx", "xxx");(2, "y", "yy", "yyy")].
The first element in the tuple is the key here.

The code I wrote used map like:

let x = [(1,"x");(2,"y")]
let y = [(1, "xx", "xxx");(2,"yy","yyy")]  
let mapY = y |> Seq.map (fun (a,b,c) -> (a, (b, c))) |> Map.ofSeq

let r = [
    for (k,v) in x do
        let (v1,v2) = mapY |> Map.tryFind k |> Option.orElse (Some ("","")) |> Option.get
        yield (k, v, v1, v2)
]

printfn "%A" r

not so gracefully.
So I wonder any better solution?(The tuple element in the question can be seq type, tuple just for example).
The key question is how to merge two seq by key gracefully.

like image 556
fairjm Avatar asked Mar 05 '23 17:03

fairjm


1 Answers

I would suggest using the query computation expression (see here for more info and examples). In your case, a solution would look like this:

let r =
    query {
        for (k1, v) in x do
        join (k2, v1, v2) in y on (k1 = k2)
        select(k1, v, v1, v2) }
    |> Seq.toList

Note that the join operator used here is in fact an inner join. There are a lot of other join-methods (as well as other operators) listed on the page linked to above.

like image 139
torbonde Avatar answered Mar 12 '23 06:03

torbonde