# Deleting one of each chosen elements in a list containing duplicates [duplicate]

I want to delete one of each (and not all) selected element in a list containing duplicates.

For example i have the list: $\{1,1,1,2,2,3\}$ and i want to delete $\{1,3\}$ so the leftover should be $\{1,1,2,2\}$ (and not $\{2,2\}$).

I tried working with $DeleteCases$ and $Alternatives$, but could only delete all elements which match the pattern:

r={1,1,1,2,2,3};
del={1,3};
DeleteCases[r, Alternatives @@ del]


Little side question: Is there a better way for adding elements than

add={4,5};


?

Thanks a lot, kon

• For your little question, Flatten[{r,add}], or AppendTo[r,add] or Join[r,add] I think should all work... Mar 24, 2015 at 14:05

You can use the fourth argument of DeleteCases to specify how many instances of a case to delete:

dcF = Fold[DeleteCases[##, 1, 1] &, ##] &;

r = {1, 1, 1, 2, 2, 3};

dcF[r, {1, 3}]
(* {1, 1, 2, 2} *)

dcF[r, {1, 1}]
(* {1, 2, 2, 3} *)

dcF[{a, a, a, 2, 2, c}, {2, 2, 2, c, c, c}]
(* {a, a, a} *)


Update:

is it possible to return {0} when trying to delete more instances of a case then r contains

delF[r_, del_] := If[Min[Count[r, #1] - #2 & @@@ Tally[del]] < 0, {0},
Fold[DeleteCases[##, 1, 1] &, r, del]]
delF[{1, 1, 1, 2, 2, 3}, {1, 1, 2, 2}]
(* {1, 3} *)
delF[{1, 1, 1, 2, 2, 3}, {1, 1, 2, 2, 2}]
(* {0} *)

• is it possible to return {0} when trying to delete more instances of a case then r contains?
– kon
Mar 24, 2015 at 16:42
• @kon, please see the update.
– kglr
Mar 24, 2015 at 17:25
• @kguler Ha! I forgot to check the docs on DeleteCases itself. Mar 24, 2015 at 17:58
• @tkott, third/fourth optional arguments are easy to forget:) When i find myself wishing a certain function handled a new/seemingly-new case i first check the docs for alternative signatures.
– kglr
Mar 24, 2015 at 18:23
• @kguler it works fine, thank you
– kon
Mar 25, 2015 at 9:12

The way I would approach this is:

delParts = First /@ (Position[r, #] & /@ del)


Then

Delete[r, delParts]


I.e., find the position of all the pieces you want, separated into groups, take the first part of each group, and delete there.

• I just realised it does not work when trying to delete two of the same element: eg.: del={1,1}
– kon
Mar 24, 2015 at 16:05
• Could it also return {0} when you try to delete more elements than r contains? Like del={3,3}?
– kon
Mar 24, 2015 at 16:31

Using pattern matching:

r = {1, 1, 1, 2, 2, 3};
del = {1, 3};

Fold[Replace, r, {{s___, #, e___} -> {s, e}} & /@ del]


{1, 1, 2, 2}