tags:

views:

90

answers:

2
+2  A: 

Well, in Don's blog about LINQ and the Powerpack:

http://blogs.msdn.com/b/dsyme/archive/2009/10/23/a-quick-refresh-on-query-support-in-the-f-power-pack.aspx

it shows off how to do LINQ join calls. But of course that's on seqs and using LINQ. He also points out that a join is like a conditional. So I think e.g. your example is like

let joinedList = [
    for v1 in l1 do
    for v2 in l2 do
    if v1.Key = v2.Parent then
    for v3 in l3 do
    if v1.Key = v3.Parent then
    yield (v1, v2, v3)] |> List.sort

though I haven't verified it on real data.

Brian
Awesome, elegant syntax and seems even more flexible than Linq-to-objects. I think I'm hooked!
Dax
@Dax: it is indeed more powerful than LINQ: the same core expressions work for lazy lists and any other computational expression.
Richard
Will this sort of expression transform into a single query (expression tree?) for LINQ-to-SQL?
YotaXP
No, if you want LINQ-to-SQL, then check out the link (Don's blog about the LINQ support in the PowerPack). @Dax was specifically asking how to do it while avoiding Linq.
Brian
+1  A: 

A first attempt using pipelines on a simplified version (ignore list3):

let res = list1
          |> Seq.collect (fun v1 -> Seq.filter (fun v2 -> v1.Key = v2.Parent) list2 |> Seq.map (fun v2 -> (v1,v2))
          |> Seq.sortBy (fun (x,y) -> x)

which will leave a IEnumerable<Tuple<T1,T2>>. A second collect and map would join the third list

Richard
Cool, I was able to come up with a generic Join function based off that: let join keySelector1 keySelector2 resultSelector list1 list2 = list1 |> List.collect (fun v1 -> list2 |> List.filter (fun v2 -> keySelector1(v1) = keySelector2(v2)) |> List.map (fun v2 -> resultSelector v1 v2))But nonetheless think I'll go with the sequence expressions approach -- so elegant and powerful!
Dax