Add seq-set-equal-p to test for set equality

* lisp/emacs-lisp/seq.el (seq-set-equal-p): Add function to compare
  two lists as if they were sets.

* test/lisp/emacs-lisp/seq-tests.el (test-seq-set-equal-p): Add test
  for seq-set-equal-p.
This commit is contained in:
Damien Cassou 2017-04-17 11:01:39 +02:00 committed by Nicolas Petton
parent 250d24fa73
commit 88f96e69cf
4 changed files with 61 additions and 0 deletions

View file

@ -792,6 +792,33 @@ it is a function of two arguments to use instead of the default @code{equal}.
@end defun @end defun
@defun seq-set-equal-p sequence1 sequence2 &optional testfn
This function checks whether @var{sequence1} and @var{sequence2}
contain the same elements, regardless of the order. If the optional
argument @var{testfn} is non-@code{nil}, it is a function of two
arguments to use instead of the default @code{equal}.
@example
@group
(seq-set-equal-p '(a b c) '(c b a))
@result{} t
@end group
@group
(seq-set-equal-p '(a b c) '(c b))
@result{} nil
@end group
@group
(seq-set-equal-p '("a" "b" "c") '("c" "b" "a"))
@result{} t
@end group
@group
(seq-set-equal-p '("a" "b" "c") '("c" "b" "a") #'eq)
@result{} nil
@end group
@end example
@end defun
@defun seq-position sequence elt &optional function @defun seq-position sequence elt &optional function
This function returns the index of the first element in This function returns the index of the first element in
@var{sequence} that is equal to @var{elt}. If the optional argument @var{sequence} that is equal to @var{elt}. If the optional argument

View file

@ -899,6 +899,9 @@ instead of its first.
* Lisp Changes in Emacs 26.1 * Lisp Changes in Emacs 26.1
** New function 'seq-set-equal-p' to check if SEQUENCE1 and SEQUENCE2
contain the same elements, regardless of the order.
+++ +++
** Emacs now supports records for user-defined types, via the new ** Emacs now supports records for user-defined types, via the new
functions 'make-record', 'record', and 'recordp'. Records are now functions 'make-record', 'record', and 'recordp'. Records are now

View file

@ -355,6 +355,12 @@ Equality is defined by TESTFN if non-nil or by `equal' if nil."
e)) e))
sequence)) sequence))
(cl-defgeneric seq-set-equal-p (sequence1 sequence2 &optional testfn)
"Return non-nil if SEQUENCE1 and SEQUENCE2 contain the same elements, regardless of order.
Equality is defined by TESTFN if non-nil or by `equal' if nil."
(and (seq-every-p (lambda (item1) (seq-contains sequence2 item1 testfn)) sequence1)
(seq-every-p (lambda (item2) (seq-contains sequence1 item2 testfn)) sequence2)))
(cl-defgeneric seq-position (sequence elt &optional testfn) (cl-defgeneric seq-position (sequence elt &optional testfn)
"Return the index of the first element in SEQUENCE that is equal to ELT. "Return the index of the first element in SEQUENCE that is equal to ELT.
Equality is defined by TESTFN if non-nil or by `equal' if nil." Equality is defined by TESTFN if non-nil or by `equal' if nil."

View file

@ -197,6 +197,31 @@ Evaluate BODY for each created sequence.
(should (seq-every-p #'identity seq)) (should (seq-every-p #'identity seq))
(should (seq-every-p #'test-sequences-evenp seq)))) (should (seq-every-p #'test-sequences-evenp seq))))
(ert-deftest test-seq-set-equal-p ()
(with-test-sequences (seq1 '(1 2 3))
(should (seq-set-equal-p seq1 seq1))
(should (seq-set-equal-p seq1 seq1 #'eq))
(with-test-sequences (seq2 '(3 2 1))
(should (seq-set-equal-p seq1 seq2))
(should (seq-set-equal-p seq2 seq1))
(should (seq-set-equal-p seq1 seq2 #'eq))
(should (seq-set-equal-p seq2 seq1 #'eq)))
(with-test-sequences (seq2 '(3 1))
(should-not (seq-set-equal-p seq1 seq2))
(should-not (seq-set-equal-p seq2 seq1))))
(should (seq-set-equal-p '("a" "b" "c")
'("c" "b" "a")))
(should-not (seq-set-equal-p '("a" "b" "c")
'("c" "b" "a") #'eq))
(should-not (seq-set-equal-p '(("a" 1) ("b" 1) ("c" 1))
'(("c" 2) ("b" 2) ("a" 2))))
(should (seq-set-equal-p '(("a" 1) ("b" 1) ("c" 1))
'(("c" 2) ("b" 2) ("a" 2))
(lambda (i1 i2) (equal (car i1) (car i2))))))
(ert-deftest test-seq-empty-p () (ert-deftest test-seq-empty-p ()
(with-test-sequences (seq '(0)) (with-test-sequences (seq '(0))
(should-not (seq-empty-p seq))) (should-not (seq-empty-p seq)))