7
$\begingroup$

Consider mapping an existing Association in a manner such as this:

asc = AssociationThread[Range @ 26, CharacterRange["a", "z"]]; Map[asc, {{11, 13, 2}, {19, 23, 16}}, {2}] 
{{"k", "m", "b"}, {"s", "w", "p"}} 

Is there a more efficient way perform this generic operation?

$\endgroup$
9
  • $\begingroup$ I guess I don't understand why I would want to Map an Association like that when the natural thing to use here is Replace or ReplaceAll. $\endgroup$ Commented Jul 27, 2014 at 14:53
  • $\begingroup$ @RunnyKine You may already have an Association object to work with and converting to Rules and then Dispatch is slow (and pointless). In fact my experimentation indicates Association is faster than `Dispatch in this application. $\endgroup$ Commented Jul 27, 2014 at 15:02
  • $\begingroup$ @RunnyKine I updated my answer to highlight the fact that use of Association is not included in the documentation for Replace that I can see. $\endgroup$ Commented Jul 27, 2014 at 15:03
  • $\begingroup$ Ah I see, I already knew they worked with Association objects, I thought I saw somewhere that almost all functions were updated to work with Associations so I just used them, didn't know this was not documented. Thanks. $\endgroup$ Commented Jul 27, 2014 at 15:07
  • $\begingroup$ I see you're shooting for the Socratic badge ;) $\endgroup$ Commented Jul 27, 2014 at 15:17

1 Answer 1

11
$\begingroup$

Although announced for 10.0.2 the functionality below works from 10.0.0 onward.


Although apparently undocumented Replace and ReplaceAll work with Association and this combination is considerably faster than Map. Further it appears to be somewhat faster than using a Dispatch table as well.

Update: it seems Lookup is faster still. See additional timing result.

Setup:

rules = Thread[Range @ 26 -> CharacterRange["a", "z"]]; asc = <|rules|>; d1 = Dispatch @ rules; d2 = Dispatch @ asc; 

Note another undocumented functionality: you can Dispatch an Association.

Test:

{{11, 13, 2}, {19, 23, 16}} /. asc Replace[{{11, 13, 2}, {19, 23, 16}}, asc, {2}] 
{{"k", "m", "b"}, {"s", "w", "p"}} {{"k", "m", "b"}, {"s", "w", "p"}} 

Timings:

time = Function[x, NumberForm[x // Timing // First // AbsoluteTiming, {4, 3}], HoldAll] m = RandomInteger[{1, 26}, {2500, 2500}]; Map[asc, m, {2}] // time m /. asc // time Replace[m, asc, {2}] // time Replace[m, d1, {2}] // time Replace[m, d2, {2}] // time Lookup[asc, #] & /@ m // time 
{1.318, 1.248} {0.843, 0.827} {0.477, 0.468} {0.576, 0.562} {0.576, 0.562} {0.380, 0.359} 

Notes:

  1. Replace at levelspec {2} is almost three times faster than the equivalent Map

  2. ReplaceAll is not as fast but still faster than Map

  3. The origin of the Dispatch table appears to have no effect on performance

  4. Although not included in the example relative timings hold with few or many rules

$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.