5
$\begingroup$

If I use the construct

f[#] & /@ f[#] & /@ f[#] & /@ {a, b, c}

my function works, but if I use

Nest[f, #, 3] & /@ {a, b, c}

it doesn't. What is the difference, and how can I code the top example without copying and pasting?

$\endgroup$
8
  • 1
    $\begingroup$ Both give the same result in Version 9.0.1.0 (Windows 8 x64). $\endgroup$
    – kglr
    Commented Feb 11, 2015 at 3:27
  • $\begingroup$ Have you tried both versions on a fresh (new) Mathematica session? $\endgroup$ Commented Feb 11, 2015 at 3:33
  • 3
    $\begingroup$ They are not the same if you define something for f. Try it with, say, f = #+1&. $\endgroup$
    – wxffles
    Commented Feb 11, 2015 at 3:37
  • $\begingroup$ as wxffles says, there is a slight difference in nesting. It can be simulated by adding parentheses. $\endgroup$
    – martin
    Commented Feb 11, 2015 at 3:43
  • 1
    $\begingroup$ Are you certain that you want a neat version of the first construct? Honest question $\endgroup$
    – Rojo
    Commented Feb 11, 2015 at 6:38

2 Answers 2

5
$\begingroup$

Analysis

Function is left-associative as converting to StandardForm reveals:

(((f[#1] &) /@ f[#1] &) /@ f[#1] &) /@ {a, b, c}

You can see the result of the rather odd operation with:

f = {#, "x"} &;

f[#] & /@ f[#] & /@ f[#] & /@ {a, b, c}
{{{{a, x}, {x, x}}, {{x, x}, {x, x}}},
 {{{b, x}, {x, x}}, {{x, x}, {x, x}}},
 {{{c, x}, {x, x}}, {{x, x}, {x, x}}}}

(Obviously the structure is specific to the output of f but I hope it serves to illustrate.)

Additionally the order of evaluation is not the same as a Map operation with a levelspec because one entire branch executes first. Compare these results:

i = 0;
f = {#, i++} &;
f[#] & /@ f[#] & /@ f[#] & /@ {a, b, c}
{{{{a, 2}, {1, 3}}, {{0, 5}, {4, 6}}},
 {{{b, 9}, {8, 10}}, {{7, 12}, {11, 13}}},
 {{{c, 16}, {15, 17}}, {{14, 19}, {18, 20}}}}
i = 0;
f = {#, i++} &;
Fold[Map[f, #, {#2}] &, {a, b, c}, Range@3]
{{{{a, 9}, {3, 10}}, {{0, 11}, {4, 12}}},
 {{{b, 13}, {5, 14}}, {{1, 15}, {6, 16}}},
 {{{c, 17}, {7, 18}}, {{2, 19}, {8, 20}}}}

I am attempting to think of a clean way to produce the first output (with arbitrary levels of mapping).

Solution

After a chat session I propose:

mapRepeated[f_, expr_, n_Integer?Positive] :=
  Nest[x \[Function] x /@ f[#] &, f, n - 1] /@ expr

Test:

i = 0;

mapRepeated[{#, i++} &, {a, b, c}, 3]
{{{{a, 2}, {1, 3}}, {{0, 5}, {4, 6}}},
 {{{b, 9}, {8, 10}}, {{7, 12}, {11, 13}}},
 {{{c, 16}, {15, 17}}, {{14, 19}, {18, 20}}}}

Using Mathematica 10 syntax the we can simplify mapRepeated slightly:

mapRepeated[f_, expr_, n_Integer?Positive] :=
  Nest[Map[#]@*f &, f, n - 1] /@ expr
$\endgroup$
5
  • 1
    $\begingroup$ Your are faster ;) so you can add that this fact may be surprising because: f /@ f /@ f /@ {a} works differently. $\endgroup$
    – Kuba
    Commented Feb 11, 2015 at 10:38
  • $\begingroup$ @Kuba Correct, Map is right-associative. $\endgroup$
    – Mr.Wizard
    Commented Feb 11, 2015 at 10:39
  • $\begingroup$ @martin If your first way is ok but second gives wrong result I'd think that the problem is in f. The question is, do you want to repeatively map f over a set? Well, you are not doing this with your first solution. (but maybe I've missed something) $\endgroup$
    – Kuba
    Commented Feb 11, 2015 at 10:44
  • 1
    $\begingroup$ @Mr.Wizard Ah, just found out that the order is important - sorry! :( $\endgroup$
    – martin
    Commented Feb 11, 2015 at 11:18
  • $\begingroup$ Let us continue this discussion in chat. $\endgroup$
    – Mr.Wizard
    Commented Feb 11, 2015 at 11:26
0
$\begingroup$

I am not sure which from of the solutions you are looking at but you can try this:

f = #+1&; 
Composition[Sequence @@ ConstantArray[f, 2]][f[#]] & /@ {a, b, c}
(*{3 + a, 3 + b, 3 + c}*)

how about this:

Nest[Map[f, #,{-1}] &, f[#], 2] & /@ {a, b, c}
$\endgroup$
8
  • $\begingroup$ Not working with my function I'm afraid - sorry to be a pain! $\endgroup$
    – martin
    Commented Feb 11, 2015 at 10:22
  • $\begingroup$ Not working at all or gives different result than you expected? $\endgroup$ Commented Feb 11, 2015 at 10:23
  • $\begingroup$ I think it must be my strangely constructed initial function. $\endgroup$
    – martin
    Commented Feb 11, 2015 at 10:24
  • $\begingroup$ It works well on the example you gave, but my function doesn't like it. $\endgroup$
    – martin
    Commented Feb 11, 2015 at 10:24
  • $\begingroup$ @Algori I'm afraid not - the first gies the same output as Nest[f, #, 3] & /@ {a, b, c}, the second gives a different output, but not the desired one. $\endgroup$
    – martin
    Commented Feb 11, 2015 at 10:32

Your Answer

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

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