9
$\begingroup$

I want to apply a function to every element of a list without taking braces into account (depth level), but with the same form of output.

Here is an example :

{a,b,{c,d},{{e}}} -> {f[a],f[b],{f[c],f[d]},{{f[e]}}}

It would be the same as applying the function to Flatten[data], but keeping the depth as is.

Let me know if I am not precise enough.

$\endgroup$

2 Answers 2

13
$\begingroup$

molekyla777's answer can be very helpful but it is not technically correct. The question specifies "every element of a list" but using a levelspec of {-1} will apply the function to every atomic element regardless of its head:

Map[f, 1 + 5 x + 10 x^2 + 10 x^3, {-1}]
f[1] + f[5] f[x] + f[10] f[x]^f[2] + f[10] f[x]^f[3]

Of course this can be very useful but it is not what was requested.

To map to every List element we can use the Listable attribute:

Function[a, f@a, Listable] @ {a, b, {c, d}, {{e}}, 1 + 10 x^3}
{f[a], f[b], {f[c], f[d]}, {{f[e]}}, f[1 + 10 x^3]}

Note that the element 1 + 10 x^3 which I added is not subdivided.

You can also set the Listable attribute of f itself if it should always be applied this way:

SetAttributes[f, Listable]

Now:

f @ {a, b, {c, d}, {{e}}, 1 + 10 x^3}
{f[a], f[b], {f[c], f[d]}, {{f[e]}}, f[1 + 10 x^3]}

Be aware that if f is given multiple arguments it will Thread as follows:

f[a, {1, 2, 3}]
{f[a, 1], f[a, 2], f[a, 3]}
f[{a, b, c}, {1, {2.1, 2.2}, 3}]
{f[a, 1], {f[b, 2.1], f[b, 2.2]}, f[c, 3]}
$\endgroup$
2
  • $\begingroup$ This should be the accepted answer IMHO. Love the use of Listable with pure function! (never realized that was even possible) $\endgroup$
    – seismatica
    Commented Aug 2, 2014 at 4:24
  • $\begingroup$ @seismatica I've known about Attribute of pure functions for a long time but the specific trick of using only its Listability is something recall learning from Rojo: (3217) $\endgroup$
    – Mr.Wizard
    Commented Aug 2, 2014 at 4:31
16
$\begingroup$

Use Map with a levelspec of {-1}:

Map[g, {a, b, {c, d}, {{e}}}, {-1}]
{g[a],g[b],{g[c],g[d]},{{g[e]}}}
$\endgroup$
1
  • $\begingroup$ Thanks a lot ! I had to do complicated codes to do this and I knew that there was a simple solution. $\endgroup$
    – Mammouth
    Commented Jul 31, 2014 at 12:13

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.