# Compare all elements of 2 lists, not necessarily in same order

Q: How to test whether all elements of two lists are the same even though the order may be different?

EXAMPLE: `(test-fn '(answered cached unread) '(unread answered cached))` => t

• Sort and compare or compare pairwise. Feb 20, 2017 at 11:05
• How would you treat duplicates, i.e. are these two lists equal under your `test-fn`? `(1 2 2 3)` and `(1 2 3)`? Feb 20, 2017 at 13:36
• @wvxvw -- The potential duplicates question is a good one -- thank you for bringing that to my attention. For purposes of this exercise, I should treat `(1 2 2 3)` and `(1 2 3)` as being equal. The answer by Erik using `cl-set-exclusive-or` looks sufficient, and I'll add a notation to the doc-string about this limitation. Feb 20, 2017 at 17:38
• Added a version catering for duplicates. Feb 20, 2017 at 22:41

Perhaps you could use your list as a set?

• `(cl-set-exclusive-or '(1 2 3) '(3 2 1))` => nil
• `(cl-set-exclusive-or '(1 2 3) '(3 2 1 0))` => (0)

You could put it into a function:

``````(defun order-independent-list-equal (list1 list2)
"Test if LIST1 and LIST2 hold the same values.
The order of values may be different."
(not (cl-set-exclusive-or list1 list2)))
``````
• `(order-independent-list-equal '(answered cached unread) '(unread answered cached))` => t

There will be a problem if you have multiple instances of the same value though. A more complex version would be something like this:

``````(defun order-independent-list-equal (list1 list2)
"Test if LIST1 and LIST2 hold the same values.
The order of values may be different."
(and (equal (length list1) (length list2))
(not (cl-set-exclusive-or list1 list2))
(let ((uniques (remove-duplicates list1)))
(cl-every
(lambda (x)
(equal (cl-count x list1)
(cl-count x list2)))
uniques))))
``````