4
$\begingroup$

Why does

assocList = {<|a->1, b->2|>, <|c->1, d->2|>};
AssociateTo[assocList[[2]], c->3]

work, but

assocList = {<|a->1, b->2|>, <|c->1, d->2|>};
ind=2; AssociateTo[assocList[[ind]], c->3]

raise error:

AssociateTo::pspec: Part specification ind is neither a machine-sized integer nor a list of machine-sized integers.

UPD

There is already a similar question, but my question should not be deleted (but closed) for to search by "AssociateTo, list" keywords.

$\endgroup$
9
  • 2
    $\begingroup$ Interestingly, AssociateTo[assocList[[1 + 1]], c -> 3] also does not work. $\endgroup$ Aug 24 at 17:15
  • $\begingroup$ @RudyPotter, thanks for attention! Well, it's something strange $\endgroup$
    – lesobrod
    Aug 24 at 17:17
  • $\begingroup$ I'm not sure AssociateTo[assocList[[2]], c -> 3] is actually "working" as it returns both parts of the list. $\endgroup$ Aug 24 at 17:19
  • $\begingroup$ AssociateTo[Evaluate[assocList[[ind]]], c -> 3] gives an odd error as well. $\endgroup$ Aug 24 at 17:20
  • $\begingroup$ This works assocList2 = assocList[[2]]; AssociateTo[assocList2, c -> 3] but this does not AssociateTo[<|c -> 1, d -> 2|>, c -> 3] I think the first term in AssociateTo has to be the name of a variable that is changeable. $\endgroup$ Aug 24 at 17:31

1 Answer 1

5
$\begingroup$

You can use With:

assocList = {<|a -> 1, b -> 2|>, <|c -> 1, d -> 2|>};
With[{ind = 2}, AssociateTo[assocList[[ind]], c -> 3]]
(*{<|a -> 1, b -> 2|>, <|d -> 2, c -> 3|>}*)

Or use Hold, ReleaseHold, and ReplaceAll:

ReleaseHold[ReplaceAll[ind -> 2][Hold[AssociateTo[assocList[[ind]], c -> 3]]]]
(*{<|a -> 1, b -> 2|>, <|d -> 2, c -> 3|>}*)
$\endgroup$
5
  • 2
    $\begingroup$ Instead of explicit holding, Unevaluated maybe more concise: Unevaluated[AssociateTo[assocList[[ind]], c -> 4]] /. ind -> 2 $\endgroup$
    – swish
    Aug 24 at 17:44
  • 1
    $\begingroup$ Great, many thanks! It works even inside a loop. But what is the magic behind this? Why Evaluate not work? $\endgroup$
    – lesobrod
    Aug 24 at 17:56
  • $\begingroup$ @lesobrod The problem is that the code first needs the part you want to replace using Set, so Evaluate doesn't work, unless you first leave it as an unevaluated expression. $\endgroup$ Aug 24 at 18:02
  • $\begingroup$ @swish You're right, it's more concise what you point out. $\endgroup$ Aug 24 at 18:06
  • 1
    $\begingroup$ For adding one key to an association AssociateTo is overkill, just use Set directly: assocList[[ind, Key[c]]] = 3 $\endgroup$
    – Jason B.
    Aug 24 at 18:36

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