开发者

How to do linq-to-IEnumerable-style joins in F#

开发者 https://www.devze.com 2023-01-07 01:15 出处:网络
I\'ve got a project that I\'m trying to convert to F#, with a fair amount of linq-to-IEnumerable style queries in it.I\'m curious what the most elegant way of doing a join of multiple lists would be i

I've got a project that I'm trying to convert to F#, with a fair amount of linq-to-IEnumerable style queries in it. I'm curious what the most elegant way of doing a join of multiple lists would be in F#. For instance if I have a bunch of C# code like the following

        var joinedList =
            from val1 in list1
            join val2 in list2 on val1.Key equals val2.Parent
            join val3 in list3 on val1.Key equals val3.Parent
            orderby val1
            select new {val1, val2, val3};

what would be the best way to translate this to F#? I'll leave open the definition of "best", but I'm looking for something functional rather than imperative, and preferably without converting my lists to seqs and/or importing System.Linq. Both lazy and eager solutions would be useful. And of course reusability is key, since I have queries like this all over. If there's any way of using workflows to make t开发者_Go百科he syntax more elegant, that would be great too.


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

Link

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.


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

0

精彩评论

暂无评论...
验证码 换一张
取 消