15
$\begingroup$

Is there a function that replaces the first occurence of the expression instead of replacing all? For example, if I have HoldForm[x + 2 + 4 + x] /. x -> 4, is there a way to return 4 + 2 + 4 + x?

$\endgroup$
  • 2
    $\begingroup$ $f_x^x$ Which one is the first x ? $\endgroup$ – Dr. belisarius Sep 23 '14 at 22:34
  • $\begingroup$ I'm not really sure, but I guess if you hit Ctrl+Shift+E, and the first occurence of x is what I meant $\endgroup$ – Yituo Sep 23 '14 at 22:36
  • $\begingroup$ What I mean is that the order of the symbols in a general math expression doesn't mean anything "in general". Perhaps if you restrict the domain of the expressions ... $\endgroup$ – Dr. belisarius Sep 23 '14 at 22:38
  • 1
    $\begingroup$ fun ClearAll[r]; r[4] := (r[4] = x; 4); HoldForm[x + 2 + 4 + x] /. x :> RuleCondition@r[4] and for less fun take a look at Position 4th arg + ReplacePart. $\endgroup$ – Kuba Sep 23 '14 at 22:41
14
$\begingroup$

Another way:

hf = HoldForm[x + 2 + 4 + x]
i = 0
hf /. (x :> 4 /; i++ == 0)

4 + 2 + 4 + x

$\endgroup$
16
$\begingroup$

Well here's a way. Find the position of the first occurrence of x:

expr = HoldForm[x + 2 + 4 + x];

pos = Position[expr, x, -1, 1];

Then:

ReplacePart[expr, pos -> 4]

4 + 2 + 4 + x

$\endgroup$
  • 6
    $\begingroup$ +1 With version 10, we can use FirstPosition, e.g. HoldForm[x + 2 + 4 + x] // ReplacePart[#, FirstPosition[#, x] -> 4] &. $\endgroup$ – WReach Sep 24 '14 at 5:22
  • $\begingroup$ @WReach I was just updating the answer with that optimization. I considered using FirstPosition but it doesn't seem to bring much benefit here (a bit of clarity I guess) so I used the general equivalent. $\endgroup$ – Mr.Wizard Sep 24 '14 at 5:24
  • $\begingroup$ @Mr.Wizard, thanks for the update, certainly cleaner :) $\endgroup$ – RunnyKine Sep 24 '14 at 5:38
  • $\begingroup$ @WReach, good point, I forgot about FirstPosition $\endgroup$ – RunnyKine Sep 24 '14 at 5:39
3
$\begingroup$

Edit

For order preserving as Jens says, I changed Attributes

ClearAttributes[Plus, Orderless]

HoldForm[7 + x + 2 + 4 + x + 5] /. f___ + x + l___ :> f + 4 + l

7 + 4 + 2 + 4 + x + 5

And you can revert by SetAttributes[Plus, Orderless]


Origin

How about this

HoldForm[x + 2 + 4 + x] /. x + a___ -> 4 + a

4 + 2 + 4 + x

$\endgroup$
  • $\begingroup$ It won't work with this example: HoldForm[7 + x + 2 + 4 + x] /. x + a___ -> 4 + a because the order isn't preserved. $\endgroup$ – Jens Sep 24 '14 at 2:25
  • $\begingroup$ @Jens : I got it, and I changed attributes. $\endgroup$ – Junho Lee Sep 24 '14 at 4:37
  • $\begingroup$ Yes, that works. But now you'd have to do the same if it were Times instead of Plus... anyway, you put your finger exactly on the reason why the original didn't work, and changing the attributes is certainly a way to make it work. $\endgroup$ – Jens Sep 24 '14 at 5:21
  • $\begingroup$ Related: (30152) $\endgroup$ – Mr.Wizard Sep 24 '14 at 5:26
  • $\begingroup$ @Jens : I see. thank you. $\endgroup$ – Junho Lee Sep 24 '14 at 5:31
2
$\begingroup$
expr = HoldForm[x + 2 + 4 + x];
expr[[##& @@ FirstPosition[expr, x]]] = 4; expr

4 + 2 + 4 + x

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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