# Replace a sequence which matches sublist with no order

Consider I have the following list with no duplicates. I would like to replace {a,c} with a number.

lst = {a,b,c,d}


Result I want is {1, b, d}. This can be in any order.

I have tried the following using SequenceReplace[] which works only if the sequence I want to replace is in the same order as in lst.

SequenceReplace[{a, b, c, d}, {b, c} -> 1]


{a,1,d}

SequenceReplace[{a, b, c, d}, {a, c} -> 1]


{a,b,c,d}

Is there a way to get {1, b, d}?

• Do you have more than one occurrence of a, ... , c, ... in your input list? If so then please update the question with more test cases.
– Syed
Commented Mar 25, 2022 at 16:18
• You cold replace a with 1 and c with Nothing: lst /. {a -> 1, c -> Nothing} Commented Mar 25, 2022 at 16:26
• @Syed the list doesn't have any duplicates. I have updated the question Commented Mar 25, 2022 at 16:31
• If you do require to work with non-adjacent sequence items, here is a possible solution: SequenceReplace[lst, {g___, a, x___, c, y___} :> Sequence[g, 1, x, y]]
– Syed
Commented Mar 25, 2022 at 16:35
• or just SequenceReplace[lst, {a, x___, c} -> Sequence[1, x]] Commented Mar 25, 2022 at 16:41

You may use OrderlessPatternSequence.

With

lst = Permutations[{a, b, c, d}]

{{a,b,c,d},{a,b,d,c},{a,c,b,d},{a,c,d,b},{a,d,b,c},{a,d,c,b}
,{b,a,c,d},{b,a,d,c},{b,c,a,d},{b,c,d,a},{b,d,a,c},{b,d,c,a}
,{c,a,b,d},{c,a,d,b},{c,b,a,d},{c,b,d,a},{c,d,a,b},{c,d,b,a}
,{d,a,b,c},{d,a,c,b},{d,b,a,c},{d,b,c,a},{d,c,a,b},{d,c,b,a}}


Then

lst /. {OrderlessPatternSequence[a, c, e___]} :> {1, e}

{{1,b,d},{1,b,d},{1,b,d},{1,b,d},{1,b,d},{1,b,d}
,{1,b,d},{1,b,d},{1,b,d},{1,b,d},{1,b,d},{1,b,d}
,{1,b,d},{1,b,d},{1,b,d},{1,b,d},{1,b,d},{1,b,d}
,{1,b,d},{1,b,d},{1,b,d},{1,b,d},{1,b,d},{1,b,d}}


Hope this helps.

• Since the pattern is orderless you don't need separate s,m,e. Just lst /. {OrderlessPatternSequence[a, c, x___]} :> {1, x} Commented Mar 25, 2022 at 19:25
• @SimonWoods Yes, you are correct. Commented Mar 25, 2022 at 20:02
\$Version

(* "13.0.1 for Mac OS X x86 (64-bit) (January 28, 2022)" *)

Clear["Global*"]

rules[lst_, target_, value_] :=
Flatten[{#[[1]] :> value, Thread[Rest[#] :> Nothing]}] &@
Select[lst, MemberQ[target, #] &]

lst = {a, b, c, d};

target = {a, c};

lst /. rules[lst, target, 1]

(* {1, b, d} )


For a more complicated example

SeedRandom[1234];

lst = RandomSample[{a, b, c, d, e, f}]

(* {a, f, d, b, e, c} *)

target = {c, a, f};

lst /. rules[lst, target, 1]

(* {1, d, b, e} *)

list = {a, b, c, d};

f = SequenceReplace[list, {OrderlessPatternSequence[#1, #2, x_]} :> Sequence[1, x]] &;

f @@@ {{a, c}, {b, d}, {a, b}}


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

lst = {a, b, c, d};


Using MapAt and DeleteElements:

rules[lst_, target_, value_] :=
Reverse@DeleteElements[Reverse@MapAt[value &, lst,
Position[lst, Alternatives @@ target]], {value} -> {value}]

rules[lst, #, 1] & /@ {{a, c}, {b, d}, {a, b}}


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

A basic approach:

func[s_, t_] :=
If[Intersection[s, t] == Sort[t],
Join[SymmetricDifference[s, t], {1}], s]


For example:

w = {a, b, c, d};
func[w, {a, c}]


yields {b, d, 1}

Or @BobHanlon example:

SeedRandom[1234];
lst = RandomSample[{a, b, c, d, e, f}]
func[lst, {c, a, f}]
`

yields: {b, d, e, 1}