Suppose I have some association a0 = <| key1 -> val1, ... |>
and some function f[key, val]
. I'd like to produce the association a1 = <| key1 -> f[key1, val1], key2 -> f[key2, val2], ... |>
.
I can see several methods to do this, each of which feels very kludgy in certain ways. In increasing order of how much they make me feel uneasy, here they are:
Way 1: Forcing the keys in with AssociationMap
, then just mapping.
RuleWithKey[Rule[key_,val_]] := Rule[key, {key, val}];
a1 = Map[f @@ #, AssociationMap[RuleWithKey, a0]].
(Related question: why does
a1 = Map[f@@#, AssociationMap[Function[ Rule[key,val], Rule[key,{key,val}] ],a0]];
not work? I get an error "Function: Parameter specification key->val
in Function[key->val,key->{key,val}]
should be a symbol or a list of symbols." but I can define RuleWithKey
just fine. Presumably this is something to do with Rule
getting evaluated in one context but not in the other?)
Way 2: Deconstructing with Keys
and KeyValueMap
, then reconstructing with AssociationThread
.
a1 = AssociationThread[Keys[a0], KeyValueMap[f, a0]];
Way 3: Creating a key-association with Identity
, then using Merge
.
a1 = Merge[ AssociationMap[Identity, Keys[a0]], a0, f@@# ];
(We can assume that we know that key /= val
always holds; there are even-more-kludgy ways to get around this, of course. Despite this assumption, this implementation particularly scares me, which is never a good thing to say about a piece of code.)
Way 4: Using Lookup
operations in an AssociationMap
.
a1 = AssociationMap[ f[#, a0[#]]&, a0 ];
Can you come up with a better method (by the admittedly difficult-to-interpret standard of "feeling not kludgy to me")?
I'm primarily interested in performant code (say associations with $\approx 10^6$ keys), so deconstructing and rebuilding associations isn't something that I'm super-thrilled about. I also don't understand what operations on associations are efficient or inefficient, so comments or answers that discuss why some of these implementations are fast or slow (relatively speaking) would also be helpful.
AssociationMap[#[[1]] -> (f @@ #) &, <|a -> 1, b -> 2, c -> 3, d -> 4|>]
? $\endgroup$Map
can); do you know of any solution that might ensure this? $\endgroup$