aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Petton2015-04-15 00:33:27 +0200
committerNicolas Petton2015-04-15 01:55:03 +0200
commit17d667b3876920652152baa4eab24134940a0f30 (patch)
treee7c8dcebf8bfc976e7212c84dc54b53ae3ced477
parent4191e54fc63be623b3a25081ab9fe03d28615fea (diff)
downloademacs-17d667b3876920652152baa4eab24134940a0f30.tar.gz
emacs-17d667b3876920652152baa4eab24134940a0f30.zip
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.
-rw-r--r--doc/lispref/sequences.texi30
-rw-r--r--lisp/emacs-lisp/seq.el29
-rw-r--r--test/automated/seq-tests.el26
3 files changed, 83 insertions, 2 deletions
diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index 1af353590cf..334b3478cb6 100644
--- a/doc/lispref/sequences.texi
+++ b/doc/lispref/sequences.texi
@@ -723,6 +723,35 @@ contain less elements than @var{n}. @var{n} must be an integer. If
723@end example 723@end example
724@end defun 724@end defun
725 725
726@defun seq-intersection sequence1 sequence2 &optional function
727 This function returns a list of the elements that appear both in
728@var{sequence1} and @var{sequence2}. If the optional argument
729@var{function} is non-@code{nil}, it is a function of two arguments to
730use to compare elements instead of the default @code{equal}.
731
732@example
733@group
734(seq-intersection [2 3 4 5] [1 3 5 6 7])
735@result {} (3 5)
736@end group
737@end example
738@end defun
739
740
741@defun seq-difference sequence1 sequence2 &optional function
742 This function returns a list of the elements that appear in
743@var{sequence1} but not in @var{sequence2}. If the optional argument
744@var{function} is non-@code{nil}, it is a function of two arguments to
745use to compare elements instead of the default @code{equal}.
746
747@example
748@group
749(seq-difference '(2 3 4 5) [1 3 5 6 7])
750@result {} (2 4)
751@end group
752@end example
753@end defun
754
726@defun seq-group-by function sequence 755@defun seq-group-by function sequence
727 This function separates the elements of @var{sequence} into an alist 756 This function separates the elements of @var{sequence} into an alist
728whose keys are the result of applying @var{function} to each element 757whose 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:
761@end example 790@end example
762@end defun 791@end defun
763 792
764
765@defmac seq-doseq (var sequence [result]) body@dots{} 793@defmac seq-doseq (var sequence [result]) body@dots{}
766@cindex sequence iteration 794@cindex sequence iteration
767 This macro is like @code{dolist}, except that @var{sequence} can be a list, 795 This macro is like @code{dolist}, except that @var{sequence} can be a list,
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index c5f5906e7e5..6f7f3c46e2a 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -4,7 +4,7 @@
4 4
5;; Author: Nicolas Petton <nicolas@petton.fr> 5;; Author: Nicolas Petton <nicolas@petton.fr>
6;; Keywords: sequences 6;; Keywords: sequences
7;; Version: 1.3 7;; Version: 1.4
8;; Package: seq 8;; Package: seq
9 9
10;; Maintainer: emacs-devel@gnu.org 10;; Maintainer: emacs-devel@gnu.org
@@ -240,6 +240,26 @@ negative integer or 0, nil is returned."
240 (setq seq (seq-drop seq n))) 240 (setq seq (seq-drop seq n)))
241 (nreverse result)))) 241 (nreverse result))))
242 242
243(defun seq-intersection (seq1 seq2 &optional testfn)
244 "Return a list of the elements that appear in both SEQ1 and SEQ2.
245Equality is defined by TESTFN if non-nil or by `equal' if nil."
246 (seq-reduce (lambda (acc elt)
247 (if (seq-contains-p seq2 elt testfn)
248 (cons elt acc)
249 acc))
250 (seq-reverse seq1)
251 '()))
252
253(defun seq-difference (seq1 seq2 &optional testfn)
254 "Return a list of th elements that appear in SEQ1 but not in SEQ2.
255Equality is defined by TESTFN if non-nil or by `equal' if nil."
256 (seq-reduce (lambda (acc elt)
257 (if (not (seq-contains-p seq2 elt testfn))
258 (cons elt acc)
259 acc))
260 (seq-reverse seq1)
261 '()))
262
243(defun seq-group-by (function seq) 263(defun seq-group-by (function seq)
244 "Apply FUNCTION to each element of SEQ. 264 "Apply FUNCTION to each element of SEQ.
245Separate the elements of SEQ into an alist using the results as 265Separate 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'."
318 (setq n (+ 1 n))) 338 (setq n (+ 1 n)))
319 n)) 339 n))
320 340
341(defun seq--activate-font-lock-keywords ()
342 "Activate font-lock keywords for some symbols defined in seq."
343 (font-lock-add-keywords 'emacs-lisp-mode
344 '("\\<seq-doseq\\>")))
345
321(defalias 'seq-copy #'copy-sequence) 346(defalias 'seq-copy #'copy-sequence)
322(defalias 'seq-elt #'elt) 347(defalias 'seq-elt #'elt)
323(defalias 'seq-length #'length) 348(defalias 'seq-length #'length)
@@ -325,5 +350,7 @@ This is an optimization for lists in `seq-take-while'."
325(defalias 'seq-each #'seq-do) 350(defalias 'seq-each #'seq-do)
326(defalias 'seq-map #'mapcar) 351(defalias 'seq-map #'mapcar)
327 352
353(add-to-list 'emacs-lisp-mode-hook #'seq--activate-font-lock-keywords)
354
328(provide 'seq) 355(provide 'seq)
329;;; seq.el ends here 356;;; seq.el ends here
diff --git a/test/automated/seq-tests.el b/test/automated/seq-tests.el
index d3536b6f9a6..7f6e06cc4b6 100644
--- a/test/automated/seq-tests.el
+++ b/test/automated/seq-tests.el
@@ -250,5 +250,31 @@ Evaluate BODY for each created sequence.
250 (should (same-contents-p list vector)) 250 (should (same-contents-p list vector))
251 (should (vectorp vector)))) 251 (should (vectorp vector))))
252 252
253(ert-deftest test-seq-intersection ()
254 (let ((v1 [2 3 4 5])
255 (v2 [1 3 5 6 7]))
256 (should (same-contents-p (seq-intersection v1 v2)
257 '(3 5))))
258 (let ((l1 '(2 3 4 5))
259 (l2 '(1 3 5 6 7)))
260 (should (same-contents-p (seq-intersection l1 l2)
261 '(3 5))))
262 (let ((v1 [2 4 6])
263 (v2 [1 3 5]))
264 (should (seq-empty-p (seq-intersection v1 v2)))))
265
266(ert-deftest test-seq-difference ()
267 (let ((v1 [2 3 4 5])
268 (v2 [1 3 5 6 7]))
269 (should (same-contents-p (seq-difference v1 v2)
270 '(2 4))))
271 (let ((l1 '(2 3 4 5))
272 (l2 '(1 3 5 6 7)))
273 (should (same-contents-p (seq-difference l1 l2)
274 '(2 4))))
275 (let ((v1 [2 4 6])
276 (v2 [2 4 6]))
277 (should (seq-empty-p (seq-difference v1 v2)))))
278
253(provide 'seq-tests) 279(provide 'seq-tests)
254;;; seq-tests.el ends here 280;;; seq-tests.el ends here