Is it possible to replace the heads to match a pattern?
eg
f[f[f[]]] -> a[b[c[]]]
or
f[f[], f[]] -> a[b[], c[]]
I looked here, but though it is related, I can't seem to apply it to this problem.
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityIs it possible to replace the heads to match a pattern?
eg
f[f[f[]]] -> a[b[c[]]]
or
f[f[], f[]] -> a[b[], c[]]
I looked here, but though it is related, I can't seem to apply it to this problem.
replaceHeads[expr_, h_, new_] :=
ReplacePart[expr, Thread[Position[expr, h] -> new]]
replaceHeads[f[f[f[]]], f, {a, b, c}]
(*a[b[c[]]]*)
replaceHeads[f[f[], f[]], f, {a, b, c}]
(*a[b[], c[]]*)
Position[...]
in Cases[..., {___, 0}]
.
$\endgroup$
– Martin Ender
Mar 28 '17 at 9:06
Quick and dirty:
replaceHeadWithSet[expr_, h_, heads_] := Module[{j = 0},
ReplaceAll[expr,
h :> (j = Mod[j + 1, Length[heads], 1]; heads[[j]])]]
Example:
replaceHeadWithSet[f[f[f[], f[]]], f, {a, b, c}]
(* Out[84]= a[b[c[], a[]]] *)
A different interpretation: the heads to replace are not all the same but the structure is fixed.
rep[h_@x___, {n_, r___}] := n @ rep[x, {r}]
rep[x___, {}] := x
Use:
rep[f[g[h[]]], {a, b, c}]
a[b[c[]]]
Using Iterator
, while it lasts:
With[{foo = GeneralUtilities`ListIterator[{a, b, c}]},
f[f[f[]]] /. f :> Read[foo]]
(* a[b[c[]]] *)
Without foo
:
f[f[], f[]] /. f :> Read[#] &@GeneralUtilities`ListIterator[{a, b, c}]
(* a[b[], c[]] *)
Fold[Replace[#1, f[expr___] -> #2[[1]][expr], {#2[[2]]}] &, f[f[f[]]],
{{a, 0}, {b, 1}, {c, 2}}]
(* a[b[c[]]] *)
however since we are replacing all the heads iteratively at each level, the current approach will substitute the same head at every level. If you dont mind having the same head for each level then one can use the approach mentioned below
Fold[Replace[#1, f[expr___] -> #2[[1]][expr], {#2[[2]]}] &, f[f[],f[]], {{a, 0}, {b, 1}}]
(* a[b[], b[]] *)
In[76]:= heads = {a, b, c}; j = 0; ReplaceAll[f[f[f[]]], f :> (j++; heads[[j]])] Out[78]= a[b[c[]]]
$\endgroup$ – Daniel Lichtblau Mar 27 '17 at 18:53f
if it doesn't appear as the head of an expression, e.g.f[f, f]
-->a[b, c]
. Is that your intention? $\endgroup$ – Martin Ender Mar 28 '17 at 8:52ReplaceAll
can be modified by changing/. f :> new
to//. f[args___] :> new[args]
. $\endgroup$ – Michael E2 Mar 28 '17 at 10:44