I want to replace a n-th pattern match in an expression with n. This is a very simple task, though it appears very hard to find an elegant implementation.

For example, with input

inp = {x, y, z, x, y, x, x, z}

I wish to compute, replacing pattern x,

{1, y, z, 2, y, 3, 4, z}

Preferably, I'd like to access the index n in the replacement rule. E.g. something like

Func[inp, x :> Symbol[m<>ToString@#]& ]

>>> {m1, y, z, m2, y, m3, m4, z}

How can I achieve this? It's trivial using Count and a For loop, but is very un-stylistic.


1 Answer 1


Consider using the Increment operator:

(*In[1]:= *)i = 1;

(*In[2]:= *)inp = {x, y, z, x, y, x, x, z};

(*In[3]:= *)inp /. x :> i++

(*Out[3]= {1, y, z, 2, y, 3, 4, z}*)

Hopefully it's obvious how this can be extended to your example using Symbol.

  • 4
    $\begingroup$ If you start with i=0 and then use inp /. x :> ++i, then at the end the index i contains the number of elements matched (instead of one more). Also, if you use inp /. x :> m[++i], then you get an indexing as desired (but without using Symbol, which may not be necessary). $\endgroup$
    – Roman
    Jan 30, 2020 at 21:31
  • $\begingroup$ A pity to have to use a variable, but it's still quite concise $\endgroup$
    – Anti Earth
    Jan 31, 2020 at 16:17
  • $\begingroup$ @Roman quite right, m[ind] is much more elegant, thanks! $\endgroup$
    – Anti Earth
    Jan 31, 2020 at 16:18
  • 1
    $\begingroup$ @AntiEarth with Block you can make i a local variable, so you don't need to worry about polluting the name space. $\endgroup$
    – Roman
    Jan 31, 2020 at 16:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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