8
$\begingroup$

Consider this example:

Complement[{a, y, c, d, e}, {a, c}, {d}]
(*{e, y}*)

However, I was expecting the result to be:

(*{y,e}*)

Why did Complement[] reorder the resulting list?

Any idea how to get the desired results (list with elements in their original order), using Complement[]?

$\endgroup$
5
  • $\begingroup$ Related, possibly duplicate? mathematica.stackexchange.com/q/1290/862 $\endgroup$ Sep 10, 2014 at 20:04
  • $\begingroup$ may be not related but instead easily found in the documentation. I was look for explanations why Complement sorts the results (the documentation says it is stored internally). $\endgroup$ Sep 10, 2014 at 20:12
  • $\begingroup$ @Simon Why not vote to close? $\endgroup$
    – Mr.Wizard
    Sep 11, 2014 at 4:53
  • $\begingroup$ Also related: (18100) $\endgroup$
    – Mr.Wizard
    Sep 11, 2014 at 5:01
  • $\begingroup$ @Mr.Wizard, it was late and I was too lazy to properly check if both questions were asking the same thing, so I just posted the link in case anyone else was looking for it. As there are still no close votes I guess the community consensus is that it's not a duplicate. $\endgroup$ Sep 11, 2014 at 9:20

5 Answers 5

8
$\begingroup$

It uses sorting internally (as documented, actually). For unsorted, could do as below.

unsortedComplement[l1_, l2_] := Reap[Module[
    {remove},
    Map[(remove[#] = True) &, l2];
    Map[If[TrueQ[remove[#]], Null, Sow[#]] &, l1];
    Clear[remove];
    ]][[2, 1]]

unsortedComplement[{1, 3, 2, 8, 5}, {3, 6}]

(* Out[78]= {1, 2, 8, 5} *)

Extending to more lists is straightforward.enter code here

$\endgroup$
1
  • $\begingroup$ Thanks. there are so many other ways to get the desired results. I was just wondering if there is any way to tell Complement to unsort the result. perhaps I should have read the document carefully. thanks for the answer $\endgroup$ Sep 10, 2014 at 20:08
7
$\begingroup$

This should get you the desired result:

 Select[{a, y, c, d, e}, MemberQ[Union[{a, c}, {d}], #] == False &]

{y, e}

$\endgroup$
6
$\begingroup$

If you want to stick with Complement[]

l = {a, y, c, d, e};;
l[[Sort[Complement[l, {a, c}, {d}] /. Thread[l -> Range@Length@l]]]]
(*{y, e}*)

or

SortBy[Complement[l, {a, c}, {d}], Position[l, #] &]
(*{y, e}*)
$\endgroup$
2
$\begingroup$
la = {a, y, c, d, e};
lb = {a, c};
lc = {d};

Since V 13.1 we have DeleteElements and UniqueElements

DeleteElements[la, Join[lb, lc]]

{y, e}

UniqueElements[{la, lb, lc}]

{{y, e}, {}, {}}

First[%]

{y, e}

$\endgroup$
2
$\begingroup$

Using DeleteCases:

DeleteCases[{a, y, c, d, e}, Alternatives @@ Union @@ {{a, c}, {d}}]

(*{y, e}*)
$\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.