I have a nested dictionary Map<'a,Map<'b,'T>>
, so that for a combination of a*b
, the entry is unique.
In order to precompute efficiently, I would need to invert the keys in a Map<'b,Map<'a,'T>>
I have some higher order methods that do the job (|/>
will apply the operation in a nested sequence |//>
the same, but 2 levels deep, |*>
will enumerate the cartesian product of nested sequence), but I am wondering if there is a better way to do this, just in case there is beautiful code to share on this one.
let reversenmap (x:Map<'a,Map<'b,'T>>) :Map<'b,Map<'a,'T>> =
let ret = x |> Map.toSeq |/> Map.toSeq |*> squash12
let ret2 = ret |> Seq.groupByn2 (fun (a,b,t) -> b)
(fun (a,b,t) -> a) |//> Seq.head
|//> (fun (a,b,c) -> c)
ret2 |> Seq.toMapn2
I think the solution from @pad is definitely more idiomatic F# than using non-standard operators like |/>
and |*>
. I would probably prefer a version that uses sequence expressions instead of Seq.collect
, which looks like this (the second part is the same as in the version from @pad):
let reverse (map: Map<'a,Map<'b,'T>>) =
[ for (KeyValue(a, m)) in map do
for (KeyValue(b, v)) in m do yield b, (a, v) ]
|> Seq.groupBy fst
|> Seq.map (fun (b, ats) -> b, ats |> Seq.map snd |> Map.ofSeq)
|> Map.ofSeq