Apply

First I define (lst) which will be used to demonstrate Apply.

lst = Table[Random[Integer, {0, 9}],     {3}, {2}, {2}, {2}]

{{{{3, 8}, {0, 4}}, {{3, 6}, {5, 8}}}, {{{3, 8}, {7, 2}}, {{8, 3}, {8, 2}}}, {{{6, 3}, {3, 6}}, {{2, 6}, {6, 2}}}}

(h@@lst) simply changes the head of list to h.

ClearAll[h, g1, g2, g3, g4] ; h @@ lst

h[{{{3, 8}, {0, 4}}, {{3, 6}, {5, 8}}}, {{{3, 8}, {7, 2}}, {{8, 3}, {8, 2}}}, {{{6, 3}, {3, 6}}, {{2, 6}, {6, 2}}}]

Starting with Mathematica 4.0 we could use  (h@@@lst)  to apply a head to all sub-expressions at a specific level.

h@@@lst

{h[{{3, 8}, {0, 4}}, {{3, 6}, {5, 8}}], h[{{3, 8}, {7, 2}}, {{8, 3}, {8, 2}}], h[{{6, 3}, {3, 6}}, {{2, 6}, {6, 2}}]}

(h@@lst)  is normally equivalent to Apply[h, expr] and  (h@@@lst)  is normally equivalent to Apply[h, lst, 1] as demonstrated in the next cell.

{h @@ lst === Apply[h, lst],   h@@@lst === Apply[h, lst, 1]}

{True, True}

If you use Apply in packages you write and you need to make the package highly reliable you should be completely explicit by using things like
Apply[h, expr, Heads→False]  or  Apply[h, expr, 1, Heads->False]  since the user of your package may have changed the default option using  SetOptions[Apply, Heads→True].

The next example changes the heads at levels 1 and 2 to h.

Apply[h, lst, 2]

{h[h[{3, 8}, {0, 4}], h[{3, 6}, {5, 8}]], h[h[{3, 8}, {7, 2}], h[{8, 3}, {8, 2}]], h[h[{6, 3}, {3, 6}], h[{2, 6}, {6, 2}]]}

The next example changes the heads at all levels from 0 down to level 2.

Apply[h, lst, {0, 2}]

h[h[h[{3, 8}, {0, 4}], h[{3, 6}, {5, 8}]], h[h[{3, 8}, {7, 2}], h[{8, 3}, {8, 2}]], h[h[{6, 3}, {3, 6}], h[{2, 6}, {6, 2}]]]

Fortunately we can Apply a function to an atomic expression without getting an error message.  In that case we simply get the atom back.

{h @@ 2, h@@@3}

{2, 3}

The heads we are changing don't have to be lists and they don't have to be the same.  Here I make a more general expression to demonstrate this.

expr = g1[{2, 3}, {3, 4}] g2[{4, 5}, {5, 6}] + g3[{6, 7}, {7, 8}] g4[{8, 9}, {9, 10}] ;

This changes the head Plus to h.

h @@ expr

h[g1[{2, 3}, {3, 4}] g2[{4, 5}, {5, 6}], g3[{6, 7}, {7, 8}] g4[{8, 9}, {9, 10}]]

This changes the head Times to h.

h@@@expr

h[g1[{2, 3}, {3, 4}], g2[{4, 5}, {5, 6}]] + h[g3[{6, 7}, {7, 8}], g4[{8, 9}, {9, 10}]]

This changes the heads g1, g2, g3, and g4 to (h).

Apply[h, expr, {2}]

h[{2, 3}, {3, 4}] h[{4, 5}, {5, 6}] + h[{6, 7}, {7, 8}] h[{8, 9}, {9, 10}]

Heads Option

Apply has a Heads option with the default setting (Heads→False).  I needed help from David Park to come up with some examples here.  In the next input Apply is used with the default setting (Heads→False), and the only sub-expression whose head is changed are Part[expr,1]→g1[2] and Part[expr,2]→g2[3].  Not including heads these are the only sub-expressions at level 1.

ClearAll[f, g1, g2, h, y] ; expr = f[y][g1[2], g2[3]] ; Apply[h, expr, 1]

f[y][h[2], h[3]]

Part[expr, 0]

f[y]

Now the previous example is repeated using (Heads→True) and (h) is applied to the sub-expression Part[expr,0]→f[y]. The expression f[y] is the head of (expr) and Apply only affects the heads when the setting (Heads→True) is used.

Apply[h, expr, 1, HeadsTrue]

h[y][h[2], h[3]]

Also read  "Further Examples" at the end of the  Apply  documentation in the Help Browser.


Created by Mathematica  (May 16, 2004)

Back to Ted’s Tricks index page