Consider this example:

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

However, I was expecting the result to be:


Why did Complement[] reorder the resulting list?

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

  • $\begingroup$ Related, possibly duplicate? mathematica.stackexchange.com/q/1290/862 $\endgroup$ – Simon Woods Sep 10 '14 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$ – Algohi Sep 10 '14 at 20:12
  • $\begingroup$ @Simon Why not vote to close? $\endgroup$ – Mr.Wizard Sep 11 '14 at 4:53
  • $\begingroup$ Also related: (18100) $\endgroup$ – Mr.Wizard Sep 11 '14 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$ – Simon Woods Sep 11 '14 at 9:20

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

unsortedComplement[l1_, l2_] := Reap[Module[
    Map[(remove[#] = True) &, l2];
    Map[If[TrueQ[remove[#]], Null, Sow[#]] &, l1];
    ]][[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

| improve this answer | |
  • $\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$ – Algohi Sep 10 '14 at 20:08

This should get you the desired result:

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

{y, e}

| improve this answer | |

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}*)


SortBy[Complement[l, {a, c}, {d}], Position[l, #] &]
(*{y, e}*)
| improve this answer | |

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.