3
$\begingroup$

I have a set:

$$A=\{\{1,2,3\},\{1,3,2\},\{2,1,3\},\{2,3,1\},\{3,1,2\},\{3,2,1\}\}$$

I want to drop elements found in sets B and C from A.

$$B=\{\{1,3,2\},\{2,1,3\}\}$$ $$C=\{\{3,1,2\},\{3,2,1\}\}$$ How can I do this?


My attempts:

A = {{1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1}}
B = {{1, 3, 2}, {2, 1, 3}}
C = {{3, 1, 2}, {3, 2, 1}}
DeleteCases[A, B]

It does not give the desired result I had to write it like this

DeleteCases[A, {1, 3, 2}]

I also tried to do it iteratively but it did not work.

$\endgroup$
6
  • 3
    $\begingroup$ Unless I'm missing something, this is exactly what Complement does $\endgroup$
    – Lukas Lang
    Commented May 10, 2022 at 20:05
  • 2
    $\begingroup$ Please start variable names with lowercase letters. Names starting with uppercase letters are used by the system. $\endgroup$
    – Syed
    Commented May 10, 2022 at 20:18
  • 1
    $\begingroup$ Here is one method. In[113]:= aA = {{1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1}}; bB = {{1, 3, 2}, {2, 1, 3}}; cC = {{3, 1, 2}, {3, 2, 1}}; DeleteCases[aA, Apply[Alternatives, Join[bB, cC]]] Out[116]= {{1, 2, 3}, {2, 3, 1}} $\endgroup$ Commented May 10, 2022 at 20:46
  • 2
    $\begingroup$ Or wait for version 13.1 and do this. In[4]:= DeleteElements[aA, Join[bB, cC]] Out[4]= {{1, 2, 3}, {2, 3, 1}} $\endgroup$ Commented May 10, 2022 at 20:48
  • $\begingroup$ One potential (documented) problem with Complement is that the output is sorted. See Complement[] changes order of elements? and How to Delete Elements from List1 appearing in List2? and UnsortedComplement, a resource function that "Delete the elements of some lists from a list x without changing either the order of x or the multiplicities of its elements" by George Beck $\endgroup$
    – user1066
    Commented May 11, 2022 at 9:25

3 Answers 3

6
$\begingroup$

This is the exact use case for Complement:

a = {{1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1}};
b = {{1, 3, 2}, {2, 1, 3}};
c = {{3, 1, 2}, {3, 2, 1}};

Complement[a, b, c]

(* Out: {{1, 2, 3}, {2, 3, 1}} *)

As an aside, do not use variable names that start with capital letters because those have customarily been reserved for built in functions. In particular, avoid using single-letter uppercase variable names like A, B, C (used as a constant in equation solving), I (the imaginary unit), E (the base of natural logarithms), K, and more: many have built-in meaning which can lead to odd behavior and hard-to-trace bugs.

$\endgroup$
5
$\begingroup$

Using DeleteCases:

This will delete any x such that x is a member of either b or c.

DeleteCases[a, x_ /; MemberQ[b, x] || MemberQ[c, x]]

Using Complement:

Complement[Complement[a, b], c]

or better still:

Fold[Complement, a, {b, c}]

Result:

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

$\endgroup$
1
  • 3
    $\begingroup$ ... or better still: Complement[a, b, c]. There is no need to apply the function twice, or to fold it over the input. $\endgroup$
    – MarcoB
    Commented May 11, 2022 at 1:38
3
$\begingroup$

One possibility to achieve this is to join all sets to be replaced and then successively delete them (note also, do not use capitalized variable names, they are reserved for the system):

a = {{1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1}};
b = {{1, 3, 2}, {2, 1, 3}};
c = {{3, 1, 2}, {3, 2, 1}};

We set tmp to a and then delete the subsets:

tmp = a;
Scan[(tmp = DeleteCases[tmp, #]) &, Join[b, c], 1];
tmp

(* {{1, 2, 3}, {2, 3, 1}} *)
$\endgroup$

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