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.
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.
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$
Commented
Mar 28, 2017 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$f
if it doesn't appear as the head of an expression, e.g.f[f, f]
-->a[b, c]
. Is that your intention? $\endgroup$ReplaceAll
can be modified by changing/. f :> new
to//. f[args___] :> new[args]
. $\endgroup$