11
$\begingroup$

How to write a nice code that removes all elements from given set A, that occur also in set B? I would like to use DeleteCases[] for this purpose, but have no good idea how to make it efficient.

SetDifference[A_,B_]:=DeleteCases[A, ??? ]

Or to find out if theres a ready to use function already, as in Lists as Sets there is nothing like that mentioned.

$\endgroup$
1
  • 1
    $\begingroup$ There is Complement but it could be not efficient enough if you know that, for example, A has no duplicates. $\endgroup$
    – Kuba
    Commented Oct 18, 2013 at 10:48

3 Answers 3

13
$\begingroup$

There is an adequate function: Complement, e.g.:

Complement[{a, b, c, d, e}, {a, c, d}]
{b, e}

It works also with more sets, lists or with any heads, e.g.:

Complement[{a, b, c, d, e}, {a}, {c, e}, {d}]
{b}
$\endgroup$
2
$\begingroup$

1. Sort order

It should be noted that Complement sorts its output:

la = {e, d, c, b, a};
lb = {a, b, c};

Complement[la, lb]

{d, e}

If we want to get the original sort order, we can use DeleteElements (new in 13.1)

DeleteElements[la, lb]

{e, d}

2. Duplicates

Complement deletes duplicates, DeleteElements doesn't

la = {e, e, d, d, c, b, a};
lb = {a, b, c};

Complement[la, lb]

{d, e}

DeleteElements[la, lb]

{e, e, d, d}

To delete duplicates when using DeleteElements:

DeleteDuplicates @ DeleteElements[la, lb]

{e, d}

$\endgroup$
1
$\begingroup$

Using DeleteCases and Union:

SetDifference[sets__?VectorQ, 
   Optional[opts : Automatic | "SortAndDistinct", Automatic]] := 
  Module[
    {setarray, sdiff, sdiffsorted},
    setarray = {sets};
    sdiff = DeleteCases[First @ setarray,
            Apply[Alternatives, Union @@ Rest[setarray]]
        ];
    sdiffsorted = Union @ sdiff;
    Switch[
            opts, Automatic,
                sdiff, "SortAndDistinct",
                sdiffsorted
        ]
   ];

   l1 = {b, e, d, a, b, c, d}; l2 = {b, c}; l3 = {a, f};

   SetDifference[l1, l2, l3]

   (*{e, d, d}*)

   SetDifference[l1, l2, l3, "SortAndDistinct"]

   (*{d, e}*)

   SetDifference[{a, b, b, d, e}, {c}, {c, e}, {d}]

   (*{a, b, b}*)

   SetDifference[{a, b, b, d, e}, {c}, {c, e}, {d}, "SortAndDistinct"]

   (*{a, b}*)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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