Re: Re: second simple problem - Follow-up

*To*: mathgroup at smc.vnet.net*Subject*: [mg99772] Re: [mg99760] Re: second simple problem - Follow-up*From*: Leonid Shifrin <lshifr at gmail.com>*Date*: Thu, 14 May 2009 01:40:12 -0400 (EDT)

It just came to my mind that another semantics may be more useful: we can isolate the rule so that it can be used in all replacement functions. In[1] = Clear[oneTimeRule]; oneTimeRule[rule : (_RuleDelayed | _Rule)] := Module[{used = False}, rule /. (head : (RuleDelayed | Rule))[lhs_, rhs_] :> head[lhs /; ! used && (used = True), rhs]]; In[2] = Range[4, 10] /. oneTimeRule[x_?OddQ -> 100] Out[2] = {4, 100, 6, 7, 8, 9, 10} In[3] = Range[4, 10] /. oneTimeRule[x_?OddQ :> x^2] Out[3] = {4, 25, 6, 7, 8, 9, 10} In[4] = {2, 3, {4, 5, 6, 7, 8}} /. oneTimeRule[x_?OddQ :> x^2] Out[4] = {2, 9, {4, 5, 6, 7, 8}} In[5] = Replace[{2, 3, {4, 5, 6, 7, 8}}, oneTimeRule[x_?OddQ :> x^2], {2}] Out[5] = {2, 3, {4, 25, 6, 7, 8}} Regards, Leonid 2009/5/13 Szabolcs Horv=E1t <szhorvat at gmail.com> > Peter Pein wrote: > > Francisco Gutierrez schrieb: > >> Dear sirs: > >> I have the following list: > >> ex={1,5,7,4,"M",6,7,8,9,1,"M",3} > >> I want to replace the M's in the following way: the first M by 5, and > the second by2. > >> Thus I have a replacement list > >> rL={5,2} > >> The problem is to get ={1,5,7,4,5,6,7,8,9,1,2,3} > >> How can I do this in the most general form (for any length of ex and a ny > number of values of "M")? > >> Thanks > >> Francisco > >> > > Hi Francisco, > > sorry for not answering. > > Can anyone please explain, why the "obvious" > > Fold[Replace[#1, "M" -> #2] &, ex, {a, b}] > > leads to an unchanged "ex"? It is nearly 3 am and I guess it is better to > go > > to sleep, than to try to solve this one. > > Hi Peter, > > You fell into the mistake of thinking that Replace will replace only the > first match in a list. The difference between Replace and ReplaceAll is > that Replace works on the whole expression by default, and not on any > subparts. We can tell it to work at a specific depth, e.g. > Replace[list, a->b, {1}] replaces elements of the list, but this will > replace *all* elements of list that match. > > I cannot remember if there is a function/syntax that replaces only the > first element found, and I cannot find one in the docs right now. If > you discover a simple way to do that, please let me know! > > Perhaps we can use Replace[#1, {be___, "M", en___} :> {be, #2, en}] &, > but that is rather ugly. >