Is the last of these results expected? If so, how?
assoc=<|"a"->1,"b"->2|>;
assoc["a"]+=1;
assoc (* <|"a" -> 2, "b" -> 2|> *)
assoc[[{"a","b"}]]=1;
assoc (* <|"a" -> 1, "b" -> 1|> *)
assoc[[{"a","b"}]]+=1;
assoc (* <|"a" -> <|"a" -> 2, "b" -> 2|>, "b" -> <|"a" -> 2, "b" -> 2|>|> *)
Edit:
Kuba helpfully points out that this reflects the behavior of Part
, specifically
assoc = <|"a" -> 1, "b" -> 2|>;
assoc[[{"a", "b"}]] (* <|"a" -> 1, "b" -> 2|> *)
Unfortunately, this pushes my question back to the behavior of Part
. We are told by the docs that Part[expr,i]
gives the i
th part of expr
and that Part[expr,{i1,i2,…}]
gives a list of the parts i1, i2, … of expr
. This seems to imply that
Part[expr, {i1,i2,...}]==(Part[expr,#]&/@{i1,i2,...})
But this is clearly not the case for associations. E.g.,
assoc[[#]] & /@ {"a", "b"} (* {1,2} *)
How am I misreading the docs?
Part
is given special instructions for some atomic objects, like sparse arrays and associations, but they don't directly return the specified parts of the underlying data structure. It was apparently decided that the benefit of this behavior outweighed the inconsistency it introduces. $\endgroup$