# How to copy with the last 1 with pattern matching method in a list?

Suppose I have a list like

{1, 2, 3, 1, 5, 8, 1, 9, 6}


The {1, 2, 3, 1, 5, 8, 9, 6} is expected. Furthermore, if we want to change the last 1 into 100 to get {1, 2, 3, 1, 5, 8, 100, 9, 6}, how to do this?

• Just for fun, without pattern matching: ReplacePart[#, Last@Position[#, 1] -> 100] &@lst or (a bit silly) ReplacePart[#, Replace[Position[#, 1], {l_ :> Last[l]}] -> 100] &@lst Commented Oct 25, 2016 at 8:49

One way:

{1, 2, 3, 1, 5, 8, 1, 9, 6} /. {x : Longest[___], 1, y___} :> {x, 100, y}
(*  {1, 2, 3, 1, 5, 8, 100, 9, 6}  *)


Another way:

{1, 2, 3, 1, 5, 8, 1, 9, 6} /. {x___, 1, y : Except[1] ...} :> {x, 100, y}
(*  {1, 2, 3, 1, 5, 8, 100, 9, 6}  *)


With

list = {1, 2, 3, 1, 5, 8, 1, 9, 6}


do

list[[Max @ Position[list, 1]]] = 100


then

list


{1, 2, 3, 1, 5, 8, 100, 9, 6}

• The Last position will be the Max number as well, so this symbol could be removed to write instead: list[[Max@Position[list, 1]]] = 100.
– user31159
Commented Oct 25, 2016 at 11:38
l = 1; ({1,2, 3,1, 5,8, 1,9, 6}[[-1 ;; 1 ;; -1]] /. 1 /; l++ == 1 -> 100)[[-1 ;; 1 ;; -1]]


You may argue [[-1 ;; 1 ;; -1]] belongs to list manipulation, then the following is a more "pattern matching" one:

l = 0; {1,2,3,1,5,8,1,9,6} /. 1 :> (l++; o@100) /. o@100 /; (--l != 0) -> 1 /. o -> (## &)

• It looks so... :)
– yode
Commented Oct 25, 2016 at 9:12
• (+1) Instead of [[-1 ;; 1 ;; -1]] you could simply apply Reverse. Commented Oct 25, 2016 at 9:34
• @AlexeyPopkov I was just pretending to write code without letter :D Commented Oct 25, 2016 at 10:42
list = {1, 2, 3, 1, 5, 8, 1, 9, 6};


Using SequenceReplace and its 3rd argument

To replace from the end we have to Reverse twice (a negative n isn't allowed).

Reverse @ SequenceReplace[Reverse @ list, {1} :> 100, 1]


{1, 2, 3, 1, 5, 8, 100, 9, 6}

To replace the first two 1:

SequenceReplace[list, {1} :> 100, 2]


{100, 2, 3, 100, 5, 8, 1, 9, 6}

list = {1, 2, 3, 1, 5, 8, 1, 9, 6}


Using FirstPosition:

g = ReplacePart[#1, -First@
FirstPosition[Reverse@#1, #2, Length@#1 + 1] -> 100] &;

g @@ {list, 1}


Using PositionIndex:

h = ReplacePart[#, Last@PositionIndex[#1][#2] -> 100] &;

h @@ {list, 1}


Result

{1, 2, 3, 1, 5, 8, 100, 9, 6}

Using Reap, Sow and Scan, we can build ReplaceLastInstance:

ReplaceLastInstance[list_List, target_, replacement_] :=
Module[{replaced = False},
Reverse@Reap[
Scan[If[! replaced && # === target, Sow[replacement];
replaced = True, Sow[#]] &, Reverse@list]][[2, 1]]]

list = {1, 2, 3, 1, 5, 8, 1, 9, 6};
ReplaceLastInstance[list, 1, 100]

(*{1, 2, 3, 1, 5, 8, 100, 9, 6}*)

list = {1, 2, 3, 1, 5, 8, 1, 9, 6}
Position[list, 1][[-1]]
ReplaceAt[list, 1 -> 100, Position[list, 1][[-1]]]


{1, 2, 3, 1, 5, 8, 100, 9, 6}

list = {1, 2, 3, 1, 5, 8, 1, 9, 6};

p = Last @ Position[list, 1]


{7}

Using MapAt

MapAt[100 &, p] @ list


{1, 2, 3, 1, 5, 8, 100, 9, 6}

Using Insert and Delete

Insert[100, p] @ Delete[p] @ list

list = {1, 2, 3, 1, 5, 8, 1, 9, 6};


Following the @eldo's idea and using SubsetReplace:

Reverse @ SubsetReplace[Reverse @ list, {1} :> 100, 1]


{1,2,3,1,5,8,100,9,6}