Commit 17d667b3 authored by NicolasPetton's avatar NicolasPetton

Add seq-intersection and seq-difference to the seq library

* lisp/emacs-lisp/seq.el (seq-intersection, seq-difference): New
functions.

* test/automated/seq-tests.el: Add tests for seq-intersection and
seq-difference.

* doc/lispref/sequences.texi: Add documentation for seq-intersection
and seq-difference.
parent 4191e54f
......@@ -723,6 +723,35 @@ contain less elements than @var{n}. @var{n} must be an integer. If
@end example
@end defun
@defun seq-intersection sequence1 sequence2 &optional function
This function returns a list of the elements that appear both in
@var{sequence1} and @var{sequence2}. If the optional argument
@var{function} is non-@code{nil}, it is a function of two arguments to
use to compare elements instead of the default @code{equal}.
@example
@group
(seq-intersection [2 3 4 5] [1 3 5 6 7])
@result {} (3 5)
@end group
@end example
@end defun
@defun seq-difference sequence1 sequence2 &optional function
This function returns a list of the elements that appear in
@var{sequence1} but not in @var{sequence2}. If the optional argument
@var{function} is non-@code{nil}, it is a function of two arguments to
use to compare elements instead of the default @code{equal}.
@example
@group
(seq-difference '(2 3 4 5) [1 3 5 6 7])
@result {} (2 4)
@end group
@end example
@end defun
@defun seq-group-by function sequence
This function separates the elements of @var{sequence} into an alist
whose keys are the result of applying @var{function} to each element
......@@ -761,7 +790,6 @@ of type @var{type}. @var{type} can be one of the following symbols:
@end example
@end defun
@defmac seq-doseq (var sequence [result]) body@dots{}
@cindex sequence iteration
This macro is like @code{dolist}, except that @var{sequence} can be a list,
......
......@@ -4,7 +4,7 @@
;; Author: Nicolas Petton <nicolas@petton.fr>
;; Keywords: sequences
;; Version: 1.3
;; Version: 1.4
;; Package: seq
;; Maintainer: emacs-devel@gnu.org
......@@ -240,6 +240,26 @@ negative integer or 0, nil is returned."
(setq seq (seq-drop seq n)))
(nreverse result))))
(defun seq-intersection (seq1 seq2 &optional testfn)
"Return a list of the elements that appear in both SEQ1 and SEQ2.
Equality is defined by TESTFN if non-nil or by `equal' if nil."
(seq-reduce (lambda (acc elt)
(if (seq-contains-p seq2 elt testfn)
(cons elt acc)
acc))
(seq-reverse seq1)
'()))
(defun seq-difference (seq1 seq2 &optional testfn)
"Return a list of th elements that appear in SEQ1 but not in SEQ2.
Equality is defined by TESTFN if non-nil or by `equal' if nil."
(seq-reduce (lambda (acc elt)
(if (not (seq-contains-p seq2 elt testfn))
(cons elt acc)
acc))
(seq-reverse seq1)
'()))
(defun seq-group-by (function seq)
"Apply FUNCTION to each element of SEQ.
Separate the elements of SEQ into an alist using the results as
......@@ -318,6 +338,11 @@ This is an optimization for lists in `seq-take-while'."
(setq n (+ 1 n)))
n))
(defun seq--activate-font-lock-keywords ()
"Activate font-lock keywords for some symbols defined in seq."
(font-lock-add-keywords 'emacs-lisp-mode
'("\\<seq-doseq\\>")))
(defalias 'seq-copy #'copy-sequence)
(defalias 'seq-elt #'elt)
(defalias 'seq-length #'length)
......@@ -325,5 +350,7 @@ This is an optimization for lists in `seq-take-while'."
(defalias 'seq-each #'seq-do)
(defalias 'seq-map #'mapcar)
(add-to-list 'emacs-lisp-mode-hook #'seq--activate-font-lock-keywords)
(provide 'seq)
;;; seq.el ends here
......@@ -250,5 +250,31 @@ Evaluate BODY for each created sequence.
(should (same-contents-p list vector))
(should (vectorp vector))))
(ert-deftest test-seq-intersection ()
(let ((v1 [2 3 4 5])
(v2 [1 3 5 6 7]))
(should (same-contents-p (seq-intersection v1 v2)
'(3 5))))
(let ((l1 '(2 3 4 5))
(l2 '(1 3 5 6 7)))
(should (same-contents-p (seq-intersection l1 l2)
'(3 5))))
(let ((v1 [2 4 6])
(v2 [1 3 5]))
(should (seq-empty-p (seq-intersection v1 v2)))))
(ert-deftest test-seq-difference ()
(let ((v1 [2 3 4 5])
(v2 [1 3 5 6 7]))
(should (same-contents-p (seq-difference v1 v2)
'(2 4))))
(let ((l1 '(2 3 4 5))
(l2 '(1 3 5 6 7)))
(should (same-contents-p (seq-difference l1 l2)
'(2 4))))
(let ((v1 [2 4 6])
(v2 [2 4 6]))
(should (seq-empty-p (seq-difference v1 v2)))))
(provide 'seq-tests)
;;; seq-tests.el ends here
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment