5
$\begingroup$

The documentation for associations says that the keys of an association are transparent for many operations. Map is one such operation. However, I am confronted with something a bit unexpected.

Clear[a, f];

a = <|1 -> <|2 -> {{6, 8}, {6, 10}}|>, 6 -> <|8 -> {{14, 18}, {2, 4}}|>|>;

f = Select[#[[2]] >= 10 &] @ # &;

f /@ a (* <|1 -> <| |>, 6 -> <| |>|> *)

f @ {{6, 8}, {6, 10}} (* {{6, 10}} *)

f @ {{14, 18}, {2, 4}} (* {{14, 18}} *)

I don't understand why f applied individually to the arguments produces the desired result, but when mapped over those same arguments inside the association, does not. What is the error in my thinking?

Thank you in advance for your help.

$\endgroup$

1 Answer 1

6
$\begingroup$

First, your construction of f is a bit malformed. You are using the operator form of Select, therefore the Select expression itself acts as a function; you do not need to add @# & to it. Use instead:

f = Select[#[[2]] >= 10 &];

The reason that your operations are not the same can be seen by mapping a dummy function foo:

foo /@ a
<|1 -> foo[<|2 -> {{6, 8}, {6, 10}}|>], 6 -> foo[<|8 -> {{14, 18}, {2, 4}}|>]|>

Because you have nested Assocations in a the function is applied to an Association rather than a List as I think you expect. We can see that simple function application does not "go inside" Association:

foo[<|2 -> {{6, 8}, {6, 10}}|>]
foo[<|2 -> {{6, 8}, {6, 10}}|>]

Depending on what you want you may be able to write simply:

Map[f] /@ a
<|1 -> <|2 -> {{6, 10}}|>, 6 -> <|8 -> {{14, 18}}|>|>

However if you want this selection to work on arbitrarily nested Associations you will need something else. One solution is this abstraction that threads a function over Association expressions:

(p : valueMap[fn_])[a_Association] := p /@ a
valueMap[fn_][other_]              := fn @ other

Now:

a2 = Append[a, 7 -> {{10, 20}, {1, 2}}];

a2 // valueMap[f]
<|1 -> <|2 -> {{6, 10}}|>, 6 -> <|8 -> {{14, 18}}|>, 7 -> {{10, 20}}|>
$\endgroup$
2
  • $\begingroup$ Thank you for the excellent answer. $\endgroup$ Sep 15, 2014 at 7:30
  • $\begingroup$ @Shredderroy You're welcome. I added an abstraction (valueMap) that simplifies the application to arbitrarily nested Associations. $\endgroup$
    – Mr.Wizard
    Sep 15, 2014 at 7:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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