# Convert association with list key to nested assocations

I have an association that maps {x, y} pairs to values, for example:

 <|{0, 0} -> "a", {-1, -4} -> "b", {-1, 1} -> "c", {-1, 0} -> "d", {1, 0} -> "e"|>


I want to convert this to a nested association with the outer association keyed by x and the inner by y:

<|0 -> <|0 -> "a"|>, -1 -> <|-4 -> "b", 0 -> "d", 1 -> "c"|>, 1 -> <|0 -> "e"|>|>


My current code is (assuming a is the association):

Apply[Association]@*Map[Last@# -> a[#] &] /@ GroupBy[Keys@a, First, Sort]


but I'm wondering if there's a more elegant way to do this (sorting not necessary).

• You could also use Association /@ rather than Apply[Association]@* in your code with same results. Jul 30, 2017 at 22:54

The following will do the same thing and avoid the sorting, but I am not sure whether it counts as "more elegant" in your book:

assoc = <|{0, 0} -> "a", {-1, -4} -> "b", {-1, 1} -> "c", {-1, 0} -> "d", {1, 0} -> "e"|>;

Association /@
GroupBy[#[[1, 1]]& -> (#[[1, 2]] -> #[[2]] &)]@
Normal@assoc

(*Out:  <|0 -> <|0 -> "a"|>, -1 -> <|-4 -> "b", 1 -> "c", 0 -> "d"|>, 1 -> <|0 -> "e"|>|> *)

• It avoids referencing the association twice, so it's definitely better than the original. Jul 30, 2017 at 23:57
Merge[
KeyValueMap[ #[[1]] -> <|#[[2]] -> #2|> &, asso]
, Association
]

<|0 -> <|0 -> "a"|>, -1 -> <|-4 -> "b", 1 -> "c", 0 -> "d"|>,  1 -> <|0 -> "e"|>|>


For deeper examples {1,2,3,4,1}->"a" etc, you may need MergeNested

• Kuba, is NestedMerge a new function? It's not documented, or do you mean Nest[Merge,f,n] Aug 3, 2017 at 21:26
• @alancalvitti I linked it, click it :)
– Kuba
Aug 3, 2017 at 21:38
• my fault, I thought false highlighting. What are the advantages of NestedMerge viz Nest[Merge,...]? Aug 3, 2017 at 21:49
• Btw, can you email me re WTC this year if you're going - re planned get together in C-U or Chi? Your contact info lists gluonvision but only Rolf's email shows up there. Aug 3, 2017 at 21:54
• @alancalvitti due to personal matters I can't go this year. Would love to meet fellow MMA users again but maybe next year.
– Kuba
Aug 3, 2017 at 22:05
keyTrie=Query[keyGroupBy[First]]/*Query[All,KeyMap[Rest]]/*Query[All,If[Keys[#1]=={{}},First[Values[#1]],keyTrie[#1]]&]


This is a recursive query that uses keyGroupBy utility:

keyGroupBy[f_][expr_]:=Association/@GroupBy[Normal[expr],Keys/*f]


<|{0, 0} -> "a", {-1, -4} -> "b", {-1, 1} -> "c", {-1, 0} ->