mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
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.
This commit is contained in:
parent
4191e54fc6
commit
17d667b387
3 changed files with 83 additions and 2 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue