12

According to the documentation, MapThread works on Association objects. But it doesn't seem to evaluate the passed function. For example:

MapThread[#1 + #2 &, {<|a -> 1, b -> 2|>, <|a -> 5, b -> 6|>}]

returns:

<|a -> (#1 + #2 &)[1, 5], b -> (#1 + #2 &)[2, 6]|>

I would have expected <| a -> 6, b -> 8 |>.

user64494
  • 26,149
  • 4
  • 27
  • 56
Niki Estner
  • 36,101
  • 3
  • 92
  • 152

4 Answers4

4

It works with V 13.3 (and maybe with some versions preceding it)

data = {<|a -> 1, b -> 2|>, <|a -> 5, b -> 6|>}

MapThread[#1 + #2 &, data]

<|a -> 6, b -> 8|>

MapThread[Plus, data]

<|a -> 6, b -> 8|>

But this fails without warnings:

MapThread[Total] @ data

<|a -> 1, b -> 2|>

Anyway, I think one should use Merge, which was specifically designed to work with Lists of Rules and Associations.

Merge[Total] @ data

<|a -> 6, b -> 8|>

Merge[Apply @ Plus] @ data

<|a -> 6, b -> 8|>

eldo
  • 67,911
  • 5
  • 60
  • 168
4

Not an answer... some observations:

Activate/@MapThread[(#+#2)&, {<|a -> 1, b -> 2|>, <|a -> 5, b -> 6|>}]
Normal@MapThread[(#+#2)&,{<|a -> 1, b -> 2|>, <|a -> 5, b -> 6|>}]
ReleaseHold/@MapThread[(#+#2)&, {<|a -> 1, b -> 2|>, <|a -> 5, b -> 6|>}]
Evaluate/@MapThread[(#+#2)&, {<|a -> 1, b -> 2|>, <|a -> 5, b -> 6|>}]
MapThread[(#+#2)&,{<|a -> 1, b -> 2|>, <|a -> 5, b -> 6|>}, 0]

all give

<|a -> 6, b -> 8|>

and, as noted by Mr. Wizard, all are equivalent to,

<|a -> 1, b -> 2|> + <|a -> 5, b -> 6|>

kglr
  • 394,356
  • 18
  • 477
  • 896
4

Evaluation with Association is at present poorly defined (IMO). See: Held keys in associations. Your example shows that MapThread does work on associations but the RHS fails to evaluate. Map causes the elements to evaluate:

MapThread[# + #2 &, {<|a -> 1, b -> 2|>, <|a -> 5, b -> 6|>}]

Identity /@ %
<|a -> (#1 + #2 &)[1, 5], b -> (#1 + #2 &)[2, 6]|>

<|a -> 6, b -> 8|>


Since there appears to be confusion with regard to the function of some different proposals in other answers and comments I feel it needs to be pointed out that several of them work by simply evaluating:

<|a -> 1, b -> 2|> + <|a -> 5, b -> 6|>

Which somewhat surprisingly yields:

<|a -> 6, b -> 8|>

As I cannot recall seeing this in the documentation I asked:

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
1

It seems that the resulting association from your code is unevaluated.

In=  MapThread[#1 + #2 &, {<|a -> 1, b -> 2|>, <|a -> 5, b -> 6|>}]
Out= <|a -> (#1 + #2 &)[1, 5], b -> (#1 + #2 &)[2, 6]|>
In=  %[a]
Out= 6

I think you can do it by

Merge[{<|a -> 1, b -> 2|>, <|a -> 5, b -> 6|>}, Total]
Y. Kwon
  • 565
  • 2
  • 8