# Map a function to every given key of a nested association

Consider for example the nested association:

myA = <|"d" -> <|"c" -> <|"a" -> 1, "b" -> 2|>|>|>


It is easy to map a function to a key on the first level:

MapAt["c" /. # &, myA, "d"]


but MapAt doesn't work with levels higher than 1

MapAt["a" /. # &, myA, "c"]


So I tried a workaround, trasforming all the associations to lists:

  Replace[
myA /. Association -> ass
,
Rule["c", x_] -> Rule["c", ("a" + "b") /. x], Infinity
] /. ass -> Association


getting the correct result, but with some errors that I can't fix

I've tried with Hold, but it looks like it works at level 1 only.

• Do you need to extract a value or is this only an example of a function "c" /. # &? p.s. it would help to have desired results presented as it is not clear what is the ultimate goal.
– Kuba
Commented Feb 10, 2020 at 11:49
• MapAt["a" /. # &, myA, {All, "c"}]?
– kglr
Commented Feb 10, 2020 at 12:34

Here is a function that finds all keys of a given name anywhere in your data structure and maps a function onto those positions:

mapAtKeyEveryWhere[assoc_, fun_, key_] := MapAt[
fun,
assoc,
Append[Key[key]] /@ Position[
assoc,
KeyValuePattern[key -> _]
]
];


Test it:

myA = <|"d" -> <|"c" -> <|"a" -> 1, "b" -> 2|>|>|>;
mapAtKeyEveryWhere[myA, ("a" + "b") /. # &, "c"]
(* <|"d" -> <|"c" -> 3|>|> *)


Is that what you have in mind?

• Perfect, thanks Sjoerd! Commented Feb 10, 2020 at 13:05