3
$\begingroup$

This is a candidate for a duplicate (probably from the documentation) but I've ironically failed to find the direct analog so far.

I have an arbitrary nested list, say:

anl = {first , second, {x, y, z}, {a, {b, c}}}

I need some MMA way to apply f to positions poss if I do not know them:

poss = {{1}, {2}, {3, 1}, {3, 2}, {3, 3}, {4, 1}, {4, 2, 1}, {4, 2, 2}}

So I need 1) an analog to:

MapAt[f, anl, poss]

{f[first], f[second], {f[x], f[y], f[z]}, {f[a], {f[b], f[c]}}}

2) a way to get poss.

Stuck a bit. Thank you for any constructive help in advance.

$\endgroup$
8
  • 1
    $\begingroup$ Do you need the positions or is something like anl /. a_Symbol :> f[a] /. f[List] :> List acceptable? $\endgroup$
    – march
    Dec 20, 2015 at 20:57
  • $\begingroup$ @march, I need to operate with leaves of large lists and associations, so positions are not a value in itself. Anyway, Replacement would qualifiy as a useful alternative. $\endgroup$
    – garej
    Dec 20, 2015 at 21:05
  • 3
    $\begingroup$ Is this what you need? l = Map[f, anl, {-1}]; Most /@ Position[l, f]? $\endgroup$
    – Kuba
    Dec 20, 2015 at 21:06
  • 4
    $\begingroup$ related: 99603 $\endgroup$
    – Kuba
    Dec 20, 2015 at 21:08
  • 2
    $\begingroup$ @Kuba This one?: mathematica.stackexchange.com/questions/98170/… $\endgroup$
    – Michael E2
    Dec 21, 2015 at 1:15

3 Answers 3

4
$\begingroup$

Is this what you need ? :

{result, poss0} = Reap[MapIndexed[(Sow[#2]; f[#1]) &, anl, {-1}]];
poss=poss0[[1]]
result

{{1}, {2}, {3, 1}, {3, 2}, {3, 3}, {4, 1}, {4, 2, 1}, {4, 2, 2}}
{f[first], f[second], {f[x], f[y], f[z]}, {f[a], {f[b], f[c]}}}

The level {-1} corresponds to all the leaves of the expression.

$\endgroup$
5
  • $\begingroup$ yes, that is what I need. Thank you for Reap/Sow solution. Frankly, I thought that some simple function exists that map at all final leaves of the tree. $\endgroup$
    – garej
    Dec 20, 2015 at 20:45
  • $\begingroup$ @garej yes, it does. You can use Map[f, anl, {-1}]. But in your question you wanted the positions of the leaves as well, and I think andre's solution is one of the most obvious ways to get this. Another could be poss = Level[MapIndexed[f, anl, {-1}], {-2}]. $\endgroup$ Dec 20, 2015 at 21:00
  • $\begingroup$ @OleksandrR., you are right, Map[f, anl, {-1}] solves a half of the problem and it is up to you to decide (I can edit the post to add the link). I'm glad to get several useful ways of doing this anyway. $\endgroup$
    – garej
    Dec 20, 2015 at 21:19
  • $\begingroup$ @garej and the other half can be solved with Level as also discussed, and as I showed in my comment above. So, if you're happy with it, I'll vote. Please note that questions closed as duplicates will not be deleted: it's just a way to organise the site. $\endgroup$ Dec 20, 2015 at 21:32
  • $\begingroup$ @Oleksandr R. @garej I don't know if in the OP mind f is intended to stay as a simple symbol or is intended to become a more complex expression, for exemple a function like x^2+x+1. In that case the solution poss=Level[MapIndexed[f,anl,{-1}],{-2}] doesn't work. $\endgroup$
    – andre314
    Dec 20, 2015 at 22:05
4
$\begingroup$

See Position

Position[anl, v_ /; ListQ[v] != True, Infinity, Heads -> False]
(* {{1}, {2}, {3, 1}, {3, 2}, {3, 3}, {4, 1}, {4, 2, 1}, {4, 2, 2}} *)
$\endgroup$
2
  • $\begingroup$ I do not need {4} and {4,2}, and {3}. I've found that positions and manually deleted unneeded =)) And (1) analog would be nice to have. $\endgroup$
    – garej
    Dec 20, 2015 at 20:37
  • $\begingroup$ See update. Added patter criteria to ignore List $\endgroup$
    – Edmund
    Dec 20, 2015 at 20:39
3
$\begingroup$
anl = {first, second, {x, y, z}, {a, {b, c}}};

pos = Position[anl, a_ /; Head@a =!= List, Heads -> False]

{{1}, {2}, {3, 1}, {3, 2}, {3, 3}, {4, 1}, {4, 2, 1}, {4, 2, 2}}

Or

pos = Position[anl, Except[_List], Heads -> False];

MapAt[g, anl, pos]

{g[first], g[second], {g[x], g[y], g[z]}, {g[a], {g[b], g[c]}}}

I would probably use

anl /. a_Except[_List] :> g@a
$\endgroup$

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