An existing high order function for this algorithm?

I came up with this simple algorithm (converts a list of tuples into a collection of keys for keys to lists) that I need in F # code:

let MergeIntoMap<'K,'V when 'K: comparison>(from: seq<'K*'V>): Map<'K,seq<'V>>= let keys = from.Select(fun (k,v) -> k) let keyValuePairs = seq { for key in keys do let valsForKey = from.Where(fun (k,v) -> key = k).Select(fun (k,v) -> v) |> seq yield key,valsForKey } keyValuePairs |> Map.ofSeq 

Input Example:

 [ ("a", 1); ("b", 2), ("a", 3) ] 

Output:

 dict [ ("a", [1; 3]), ("b", [2]) ] 

And I thought it should be something that already exists in BCL or F #, consisting of high-order functions? If so, can someone contact me? Because I'm sure my code is not very efficient as it is ...

+5
source share
1 answer

It seems you want to get something like this

 let toGroupMap x = x |> Seq.groupBy fst |> Seq.map (fun (k,v) -> k, v |> Seq.map snd |> Seq.toArray) |> Map.ofSeq 

FSI:

 val toGroupMap : x:seq<'a * 'b> -> Map<'a,'b []> when 'a : comparison val input : (string * int) list = [("a", 1); ("b", 2); ("a", 3)] val output : Map<string,int []> = map [("a", [|1; 3|]); ("b", [|2|])] 

Edit

As Fyodor Soikin wrote in a comment, there is a ToLookup extension method that probably does what you need.

 open System.Linq let output = input.ToLookup(fst, snd) 

Here you can read about the difference between the ILookup and IDictionary

+4
source

Source: https://habr.com/ru/post/1264735/


All Articles