4
$\begingroup$

This question already has an answer here:

Is there a way to apply a function h to the following nested list

{{a, b}, {c, d}, {{d, e }, {f, g}}} 

where this should should become

{h[a], h[c], {h[d], h[f]}}

h is applied to the first element of each (deepest nested) sublist, replacing this sublist. The nesting is never deeper than the example displayed above; i.e., the expression tree for the list has at most depth 3.

The rest of the list structure pattern is preserved.

Here, a, c, d and f are not atoms. They are again expressions with heads. The heads are however not list-heads.

As an example, consider

{{u[a], u[b]}, {u[v[c]], d}, {{d, e}, {f, g}}}   

applying h to this should yield:

{h[u[a]], h[u[v[c]]], {h[d], h[f]}}

In other words, h is applied to the "leaves" of the list expression given above, where these "leaves" are more complicated expressions.

$\endgroup$

marked as duplicate by Michael E2, Community Jun 22 at 17:33

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    $\begingroup$ You can format inline code and code blocks by selecting the code and clicking the {} button above the edit window. The edit window help button ? is useful for learning how to format your questions and answers. You may also find this meta Q&A helpful $\endgroup$ – Michael E2 Jun 22 at 0:32
  • 1
    $\begingroup$ Possible duplicate: mathematica.stackexchange.com/questions/56300/… -- the accepted answer (Mr. Wizard's) works for this case, and is virtually the same as mine below. $\endgroup$ – Michael E2 Jun 22 at 0:39
3
$\begingroup$

You can use the Listable attribute. Give the attribute to h or a wrapper-function as below:

Module[{hh},
 SetAttributes[hh, Listable];
 hh[x__] := h[x];
 hh@{{u[a], u[b]}, {u[v[c]], d}, {{d, e}, {f, g}}}
 ]
(*  {{h[u[a]], h[u[b]]}, {h[u[v[c]]], h[d]}, {{h[d], h[e]}, {h[f], h[g]}}}  *)

Also:

Function[, h[##], Listable]@{{u[a], u[b]}, {u[v[c]], d}, {{d, e}, {f, g}}}
$\endgroup$
  • 2
    $\begingroup$ Strange. The expected output from the OP does not match your output, as he wanted the first element of a list to get wrapped in h, and the others to be dropped. Yet, he did accept this answer. So, I'm confused. $\endgroup$ – Carl Woll Jun 22 at 17:39
  • $\begingroup$ @CarlWoll Yeah, I missed that. Nobody said anything until now... $\endgroup$ – Michael E2 Jun 22 at 17:43
  • $\begingroup$ Ok, I realize that the first element was not kept, but the answer suited me best and the change is only minor. $\endgroup$ – Mike Jun 22 at 18:13
5
$\begingroup$

ReplaceAll with replacement rule {x_, y : Except[___List]} :> h[x]:

{{a, b}, {c, d}, {{d, e}, {f, g}}} /. {x_, y : Except[___List]} :> h[x]

{h[a], h[c], {h[d], h[f]}}

{{u[a], u[b]}, {u[v[c]], d}, {{d, e}, {f, g}}} /. {x_, y : Except[___List]} :> h[x]

{h[u[a]], h[u[v[c]]], {h[d], h[f]}}

$\endgroup$
  • $\begingroup$ Happy 200K! That represents a lot of work and a lot of help given to others! $\endgroup$ – Michael E2 Jun 22 at 1:52
  • $\begingroup$ Thank you @Michael -- it has been a lot of fun. $\endgroup$ – kglr Jun 22 at 2:04
  • $\begingroup$ Thanks! I like the Listable comment below and it seems that your solution works by excepting lists. A related question I wonder about is whether one can apply a function to any expression having a fixed type of head, but not to other expressions? It's a bit of a derail from the original topic, but the answers made me wonder about that aspect. $\endgroup$ – Mike Jun 22 at 17:37
5
$\begingroup$

You can use Replace with a level of All:

Replace[
    {{a,b},{c,d},{{d,e},{f,g}}},
    {x:Except[_h],y:Except[_h]} :> h[x],
    All
]

{h[a], h[c], {h[d], h[f]}}

Using Replace with a level of All does a depth first (bottom up) replacement. Using ReplaceAll instead uses a top down replacement:

ReplaceAll[
    {{a,b},{c,d},{{d,e},{f,g}}},
    {x:Except[_h],y:Except[_h]} :> h[x]
]

{h[a], h[c], h[{d, e}]}

$\endgroup$
  • $\begingroup$ Not entirely sure this does the trick when a, b etc are not atoms, but expressions that are not lists. I could be wrong. $\endgroup$ – Mike Jun 22 at 17:32
  • $\begingroup$ @Mike Do you mean an argument like {{a, b}, {k[{c, l}], d}, {{d, e}, {f, g}}}? $\endgroup$ – Michael E2 Jun 22 at 18:23
  • $\begingroup$ I mean arguments like: {{u[a], u[b]}, {u[v[c]], d}, {{d, e}, {f, g}}} $\endgroup$ – Mike Jun 22 at 18:47

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