16

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?

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
Yituo
  • 1,389
  • 9
  • 15
  • 2
    $f_x^x$ Which one is the first x ? – Dr. belisarius Sep 23 '14 at 22:34
  • I'm not really sure, but I guess if you hit Ctrl+Shift+E, and the first occurence of x is what I meant – Yituo Sep 23 '14 at 22:36
  • 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 ... – Dr. belisarius Sep 23 '14 at 22:38
  • 1
    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. – Kuba Sep 23 '14 at 22:41

4 Answers4

16

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

Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
RunnyKine
  • 33,088
  • 3
  • 109
  • 176
  • 6
    +1 With version 10, we can use FirstPosition, e.g. HoldForm[x + 2 + 4 + x] // ReplacePart[#, FirstPosition[#, x] -> 4] &. – WReach Sep 24 '14 at 05:22
  • @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. – Mr.Wizard Sep 24 '14 at 05:24
  • @Mr.Wizard, thanks for the update, certainly cleaner :) – RunnyKine Sep 24 '14 at 05:38
  • @WReach, good point, I forgot about FirstPosition – RunnyKine Sep 24 '14 at 05:39
14

Another way:

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

4 + 2 + 4 + x

mfvonh
  • 8,460
  • 27
  • 42
3

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

Junho Lee
  • 5,155
  • 1
  • 15
  • 33
2
expr = HoldForm[x + 2 + 4 + x];
expr[[##& @@ FirstPosition[expr, x]]] = 4; expr

4 + 2 + 4 + x

kglr
  • 394,356
  • 18
  • 477
  • 896