0
$\begingroup$

This question already has an answer here:

This seems like a very simple action:

{a, b, c, d, e, f} //. {r___, x_, y___} :> {r, 1, y}

but it replaces only the first element giving

{1, b, c, d, e, f}

Why? what am i doing wrong? The specified pattern seems to describe every element of the list..

Clarification. I want to change all elements of the given list to 1 using ReplaceRepeated only. For a list of symbols it is straightforward:

 {a, b, c, d, e, f} //. {r___, x_Symbol, y___} :> {r, 1, y}
{1, 1, 1, 1, 1, 1}

But what if the list has elements of different type?

And another tweak on this problem. What if i want to modify list elements using only patterns such as:

 someFun[n_?EvenQ] := n + 1;
          someFun[n_?OddQ] := 2*n;
          Replace[{1, 2, 3}, {r___, x_, y___} :> {r, someFun[x], y}]
{2,2,3}

I could do it using

 Map[someFun,{1,2,3}]
{2,3,6}

but still would like to do it using pattern. Is it possible?

$\endgroup$

marked as duplicate by Mr.Wizard pattern-matching Jul 17 '17 at 6:46

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • $\begingroup$ Default behavior is longest match.... $\endgroup$ – ciao Mar 21 '15 at 5:47
  • $\begingroup$ I understand. Is it possible to use only patterns to force list iteration and subsequent substitution? $\endgroup$ – user3826801 Mar 21 '15 at 5:54
  • $\begingroup$ Add to your OP what it is you're trying to accomplish - iteration with your pattern (or fixedpoint with it) would give same results... $\endgroup$ – ciao Mar 21 '15 at 5:55
  • $\begingroup$ {a, b, c, d, e, f} //. {r___, Except[1], y___} -> {r, 1, y} produces {1, 1, 1, 1, 1, 1} $\endgroup$ – m_goldberg Mar 21 '15 at 14:26
4
$\begingroup$

Your pattern matches <nothing><a><bcdef> so the a is replaced with 1. Next pass, the pattern matches <nothing><1><bcdef>, since replacement would result in no change, replacement stops.

It's not clear from the OP in its current state what it is you want to accomplish. Add that info, and you'll surely get responses.

It seems you might be after

ReplaceList[{a, b, c, d, e, f}, {r___, x_, y___} :> {r, 1, y}]

giving

{{1, b, c, d, e, f}, {a, 1, c, d, e, f}, {a, b, 1, d, e, f}, {a, b, c,
   1, e, f}, {a, b, c, d, 1, f}, {a, b, c, d, e, 1}}

but again, your OP needs to be clarified.

Per your update, if all you want is all elements replace by 1, no need for ReplaceRepeated, just use something like

lst={a,b,c,d,e,f}
Replace[lst, _ -> 1, 1]

Or even faster for big lists

ConstantArray[1,Length@lst]
$\endgroup$
1
$\begingroup$

To answer your more general question of how to apply an arbitrary function using your replacement scheme, you can do it like this:

f[x_] := x^2 + 1
First /@ 
  (Range[6] //. {r___, x : Except[tagged[___]], y___} -> {r, tagged[f[x]], y})
{2, 5, 10, 17, 26, 37}

But that's rather silly, isn't it? It's just doing Map in a very obscure and much slower way.

f /@ Range[6]
{2, 5, 10, 17, 26, 37}
$\endgroup$
2
$\begingroup$

It appears that the BlankNullSequence defaults to matching zero arguments, if possible. Try this:

{a, b, c, d, e, f} //. {x__, y___} :> {y, 1}

{1,1,1,1,1,1}

$\endgroup$
  • $\begingroup$ Thanks! This works fine for such straightforward replacement, but when i try to do modification such as: {1, 2, 3} //. {x__, y___} :> {y, someFun[x]} the evaluation runs into an infinite loop. Why? $\endgroup$ – user3826801 Mar 21 '15 at 6:38
  • $\begingroup$ Because at some point zentient's solution stops changing the list (when it becomes a list of 1s, further application of his rule does not alter anything), while repeated application of somefun as in OP will indefinitely increase the values of the elements. $\endgroup$ – LLlAMnYP Mar 21 '15 at 8:52

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