I've come up with this simple algorithm (convert list of tuples to a map collection of keys to lists) that I needed in my 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
Example input:
[ ("a", 1); ("b", 2), ("a", 3) ]
Output:
dict [ ("a", [1; 3]), ("b", [2]) ]
And I was thinking this must be something that is already in the BCL or F#'s set of high order functions maybe? If yes, can someone reference me to it? Because I'm sure my code is not very efficient as it is...
It seems you want to get something like that
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 written Fyodor Soikin in the comments, there is a extension method ToLookup
, which probably does what you need.
open System.Linq
let output = input.ToLookup(fst, snd)
You can read here about the difference between ILookup and IDictionary interfaces
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With