5
$\begingroup$

With an Association we can update keys in place two ways:

a=_Assocation
(Set|SetDelayed)[a[key],value]
(*OR*)
AssociateTo[a,(Rule|RuleDelayed)[key,value]]

The second syntax has the distinct benefit of being able to update multiple values at once:

AssociateTo[a,{(Rule|RuleDelayed)[key,value]..}]

Unfortunately I haven't found a nice way to update multiple Associations at once (in place).

I would have hoped this would work:

a = <||>;
b = <||>;
AssociateTo[{a, b}, 1 -> 2]
(*a = <| 1 -> 2 |>; b = <| 1 -> 2|>*)

But it just gives me a Protected message and a and b remain unaltered. Similarly the docs provide nothing of note.

Is there anyway to do something like that?

This is a seemingly small thing, but it would free me from having to jump through the hoops of keeping my arguments sufficiently held in a Scan call and could potentially be more efficient to do many updates at once when all the key edits are the same.

$\endgroup$
3
$\begingroup$

I don't know of a built-in way to do this but it is easy enough to implement it ourselves.

SetAttributes[AssociateToAll, HoldFirst]

AssociateToAll[{sym__Symbol}, rls_] :=
  Hold[sym] // Cases[ x_ :> AssociateTo[x, rls] ]

a = <||>;
b = <||>;

AssociateToAll[{a, b}, 1 -> 2];

a
b
<|1 -> 2|>

<|1 -> 2|>
$\endgroup$
  • $\begingroup$ This is basically what I'm doing now, I don't actually have that Symbol there because the AssociateTo calls are operating on an inner part of my main Association. You're right that it might be worth into a proper function, though. Currently just doing Function[Null,_,HoldFirst] $\endgroup$ – b3m2a1 Apr 1 '17 at 21:38
  • $\begingroup$ @MB1965 Sorry if this isn't helpful. I just changed my code a little to use Cases; perhaps it will give you some additional ideas. $\endgroup$ – Mr.Wizard Apr 1 '17 at 21:41
  • $\begingroup$ it's helpful to know how other people would do it, if there's no built in way. Your syntax is is more compact than what I've been doing. $\endgroup$ – b3m2a1 Apr 1 '17 at 21:42
2
$\begingroup$

If you are manipulating sets of Association objects then you may be interested in Dataset.

a = <||>;
b = <||>;

ds = Dataset[{a, b}];
{a, b} = Normal[ds[All, <|1 -> (2 &)|>]]

{<|1 -> 2|>, <|1 -> 2|>}

Wrapped up in a function:

AssociateToAll[assocs_, c_ -> v_] := Normal@Dataset[assocs][All, <|c -> (v &)|>]
AssociateToAll[{a, b}, 1 -> 2]

{<|1 -> 2|>, <|1 -> 2|>}

Even though this is not really how Dataset is meant to be used.

$\endgroup$
  • $\begingroup$ This is potentially a good alternate route. Any idea how this'll perform vs Mr.Wizard's truly in-place version? I'm adding vectorized attribute setting in an OOP system of mine. $\endgroup$ – b3m2a1 Apr 1 '17 at 22:01
  • $\begingroup$ @MB1965 I don't know. $\endgroup$ – C. E. Apr 1 '17 at 22:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.