3

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

4
  • Sort and compare or compare pairwise.
    – politza
    Feb 20, 2017 at 11:05
  • 2
    How would you treat duplicates, i.e. are these two lists equal under your test-fn? (1 2 2 3) and (1 2 3)?
    – wvxvw
    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.
    – lawlist
    Feb 20, 2017 at 17:38
  • 1
    Added a version catering for duplicates. Feb 20, 2017 at 22:41

1 Answer 1

3

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

Your Answer

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

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