5
$\begingroup$

Is there any way to simplify the following pattern:

{p___, {a___, x_, x_, b___}, q___} :> {p, {a, x, b}, q}

Ie. where I remove duplicated elements within sublists?

Edit: Just to be clear, I have the feeling p and q could be removed here, but well I'm not certain :)

Thanks

$\endgroup$
3
  • $\begingroup$ Think. If you remove the p and q and you happened to have two adjacent sublists that were identical, what would happen then? Something like {{3,4},{5,7,7,2},{5,7,7,2},{2,8}} Compare that example with and without the p and q and see what happens. Then think about it until you can explain what happened. Then try all this using /. and //. It all depends on what you want to accomplish. $\endgroup$ – Bill Oct 9 '14 at 19:56
  • $\begingroup$ Well exactly, that's why I kept them. But since p and q remain at the same place I thought I could have removed them. Besides, it assumes here that I'm working at the second level of my main list, but what if I didn't know which level they were at? Anyway, it might just be the most simple expression but I had the intuition it wasn't so. And btw it's a repeated pattern //. here. $\endgroup$ – Literal Oct 9 '14 at 20:07
  • $\begingroup$ You could look at DeleteDuplicates or Split + First $\endgroup$ – mfvonh Oct 9 '14 at 20:51
5
$\begingroup$

Several demonstrative examples:

list = {{1, 2, 3}, {1, 2, 3}, {1, 2, 2, 3}, {1, 3, 3, 5}};

list /. {p___, {a___, x_, x_, b___}, q___} :> {p, {a, x, b}, q}
(* {{1, 2, 3}, {1, 2, 3}, {1, 2, 3}, {1, 3, 3, 5}} *)

list /. {a___, x_, x_, b___} :> {a, x, b}
(* {{1, 2, 3}, {1, 2, 2, 3}, {1, 3, 3, 5}} *)

Replace[list, {a___, x_, x_, b___} :> {a, x, b}, {1}]
(* {{1, 2, 3}, {1, 2, 3}, {1, 2, 3}, {1, 3, 5}} *)

I think the last one is what you are looking for.

If you want to delete many sequential duplicates with patterns you can use

Replace[list, {a___, Repeated[x_, {2, ∞}], b___} :> {a, x, b}, {1}]
$\endgroup$
2
  • $\begingroup$ Sweet. Yeah the last answer with the levelspec argument is what I was looking for. It's too bad it can't be expressed using the /. syntax though. One last question, I'm not certain why the first pattern (the which I submitted doesn't catch the {1, 3, 3, 5} list. $\endgroup$ – Literal Oct 9 '14 at 21:10
  • $\begingroup$ @Neuschwanstein It is because the whole list matches the pattern and /. applies the substitution, but this substitution eliminate only one duplicate. You should use //. (ReplaceRepeated) to apply replacement repeatedly. Note, that ReplaceRepeated is very slow for big lists due to matching the whole list a lot of times. $\endgroup$ – ybeltukov Oct 9 '14 at 21:28
3
$\begingroup$

Map ReplaceAll at Level 1:

# /. {a___, x_, x_, b___} :> {a, x, b} & /@ list
(* {{1, 2, 3}, {1, 2, 3}, {1, 2, 3}, {1, 3, 5}} *)

Map DeleteDuplicates at Level 1:

DeleteDuplicates /@ list
(* {{1, 2, 3}, {1, 2, 3}, {1, 2, 3}, {1, 3, 5}} *)

Alternative methods to ReplaceRepeated to get {{1, 2, 3}, {1, 3, 5}}:

FixedPoint[# /. {a___, x_, x_, b___} :> {a, x, b} &, list]
(* {{1, 2, 3}, {1, 3, 5}} *)

Map[DeleteDuplicates, list, {0, 1}]
(* {{1, 2, 3}, {1, 3, 5}} *)

And to get {{1, 2, 3}, {1, 2, 2, 3}, {1, 3, 3, 5}}:

Map[# /. {a___, x_, x_, b___} :> {a, x, b} &, list, {0}]
(* {{1, 2, 3}, {1, 2, 2, 3}, {1, 3, 3, 5}} *)

or

Map[DeleteDuplicates, list, {0}]
(* {{1, 2, 3}, {1, 2, 2, 3}, {1, 3, 3, 5}} *)
$\endgroup$
1
$\begingroup$

If I don't missunderstand your question this could be a good candidat for ReplaceRepeated

list = {1, 1, 2, 3, 3, 3, 1, 1, 7};

list //. {head___, x_, x_, tail___} :> {head, x, tail}

{1, 2, 3, 1, 7}

To scrutinise @ ybeltukov's excellent answer and your nice but ambiguous question

matrix = {{1, 2, 3}, {1, 2, 3}, {1, 2, 2, 3}, {1, 3, 3, 5}};

matrix //. {head___, x_, x_, tail___} :> {head, x, tail}

{{1, 2, 3}, {1, 3, 5}}

$\endgroup$
1
$\begingroup$

Another option to consider is to only (repeatedly) replace if the repeated item is an atom:

rule = {a___, x_?AtomQ, x_, b___} :> {a, x, b}

In action:

{{1, 2, 3}, {1, 2, 3}, {1, 2, 2, 3}, {1, 3, 3, 5}} //. rule

{{1, 2, 3}, {1, 2, 3}, {1, 2, 3}, {1, 3, 5}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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