0

I have 2 lists of records with one same label id1. I need a way to join them.

type A = { id1: int; name: string }

type B = { id1: int; id2: Option<int> }

let a1 = { id1 =  1; name = "nafis" }
let a2 = { id1 =  2; name = "habib" }

let b1 = { id1 = 1; id2 = Some(5) }
let b2 = { id1 = 1; id2 = None }
let b3 = { id1 = 2; id2 = None }

let a = [a1; a2]
let b = [b1; b2; b3]

printfn "%A" a =>  [({id1 = 1;name = "nafis";}, {id1 = 2;name = "habib";})]
printfn "%A" b =>  
[({id1 = 1; id2 = Some 5;}, {id1 = 1; id2 = None;}, {id1 = 2;id2 = None;})]

How can I join this 2 lists based on id1?

I want an output like this =>

[({id1 = 1;name = "nafis"; id2 = [Some 5; None];}, {id1 = 2;name = "habib"; id2 =[None];})]

Some form of tutorial or blog link will be helpful.

Nafis Islam
  • 1,483
  • 1
  • 14
  • 34
  • Does [this question](https://stackoverflow.com/questions/4787226/merge-multiple-lists-of-data-together-by-common-id-in-f) help you out? – KevinLamb Jul 04 '19 at 16:56
  • no I can not create list of lists of items. list `a` and `b` are different types. – Nafis Islam Jul 04 '19 at 17:00
  • 3
    There's no magic way to merge two arbitrary types together. You'll simply have to define the merged type and write the conversion code yourself. Unless you can be more specific about any problem you have doing so, I think this question is too broad. – glennsl Jul 04 '19 at 17:10
  • 3
    F# query expressions have a `join` operator: https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/query-expressions - you will have to create the "joined type" as well as the handling of the join result yourself, though. – TeaDrivenDev Jul 04 '19 at 17:18

1 Answers1

3

MSDN: Query expressions enable you to query a data source and put the data in a desired form. Query expressions provide support for LINQ in F#.

As correctly mentioned in the comments, you need to have a third type C that will host the joined result and then use good old LINQ to join the lists:

type A = { id1: int; name: string }
type B = { id1: int; id2: Option<int> }
type C = { id1: int; name: string; id2: Option<int> }

let a1 = { id1 =  1; name = "nafis" }
let a2 = { id1 =  2; name = "habib" }

let b1 = { id1 = 1; id2 = Some(5) }
let b2 = { id1 = 1; id2 = None }
let b3 = { id1 = 2; id2 = None }

let a = [a1; a2]
let b = [b1; b2; b3]

let result (a:A list) (b: B list) = query {
    for list1 in a do
    join list2 in b on
        (list1.id1 = list2.id1)
    select {id1 = list1.id1; name = list1.name; id2= list2.id2}
}

let c = result a b |> List.ofSeq

Result:

val c : C list = [{id1 = 1;
               name = "nafis";
               id2 = Some 5;}; {id1 = 1;
                                name = "nafis";
                                id2 = None;}; {id1 = 2;
                                               name = "habib";
                                               id2 = None;}]
3615
  • 3,787
  • 3
  • 20
  • 35