diff options
| author | Nicolas Petton | 2015-02-06 15:55:57 +0100 |
|---|---|---|
| committer | Nicolas Petton | 2015-02-06 15:55:57 +0100 |
| commit | c4a0eff0112298de0a97b63e4e22826bf2b4126c (patch) | |
| tree | 8cf3babd3fcb25769c6cd36a52bb7753b143bbe2 | |
| parent | 05211a578ed2c52f6ed818fc173561afbaea54c2 (diff) | |
| download | emacs-c4a0eff0112298de0a97b63e4e22826bf2b4126c.tar.gz emacs-c4a0eff0112298de0a97b63e4e22826bf2b4126c.zip | |
Add seq-partition and seq-group-by
* lisp/emacs-lisp/seq.el: Better docstring for seq.el functions
* test/automated/seq-tests.el: New tests for seq-partition and
seq-group-by
| -rw-r--r-- | lisp/ChangeLog | 2 | ||||
| -rw-r--r-- | lisp/emacs-lisp/seq.el | 27 | ||||
| -rw-r--r-- | test/ChangeLog | 5 | ||||
| -rw-r--r-- | test/automated/seq-tests.el | 16 |
4 files changed, 47 insertions, 3 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index aa58c5349aa..0cd2a4d04e8 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | 2015-02-06 Nicolas Petton <nicolas@petton.fr> | 1 | 2015-02-06 Nicolas Petton <nicolas@petton.fr> |
| 2 | 2 | ||
| 3 | * emacs-lisp/seq.el (seq-mapcat): New function. | 3 | * emacs-lisp/seq.el (seq-mapcat, seq-partition, seq-group-by): New functions. |
| 4 | 4 | ||
| 5 | 2015-02-06 Artur Malabarba <bruce.connor.am@gmail.com> | 5 | 2015-02-06 Artur Malabarba <bruce.connor.am@gmail.com> |
| 6 | 6 | ||
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index bd234a3b55a..cd45989eca8 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el | |||
| @@ -230,6 +230,33 @@ The result is a sequence of type TYPE, or a list if TYPE is nil." | |||
| 230 | (apply #'seq-concatenate (or type 'list) | 230 | (apply #'seq-concatenate (or type 'list) |
| 231 | (seq-map function seq))) | 231 | (seq-map function seq))) |
| 232 | 232 | ||
| 233 | (defun seq-partition (seq n) | ||
| 234 | "Return a list of the elements of SEQ grouped into sub-sequences of length N. | ||
| 235 | The last sequence may contain less than N elements. If N is a | ||
| 236 | negative integer or 0, nil is returned." | ||
| 237 | (unless (< n 1) | ||
| 238 | (let ((result '())) | ||
| 239 | (while (not (seq-empty-p seq)) | ||
| 240 | (push (seq-take seq n) result) | ||
| 241 | (setq seq (seq-drop seq n))) | ||
| 242 | (nreverse result)))) | ||
| 243 | |||
| 244 | (defun seq-group-by (function seq) | ||
| 245 | "Apply FUNCTION to each element of SEQ. | ||
| 246 | Separate the elements of SEQ into an alist using the results as | ||
| 247 | keys. Keys are compared using `equal'." | ||
| 248 | (nreverse | ||
| 249 | (seq-reduce | ||
| 250 | (lambda (acc elt) | ||
| 251 | (let* ((key (funcall function elt)) | ||
| 252 | (cell (assoc key acc))) | ||
| 253 | (if cell | ||
| 254 | (setcdr cell (push elt (cdr cell))) | ||
| 255 | (push (list key elt) acc)) | ||
| 256 | acc)) | ||
| 257 | seq | ||
| 258 | nil))) | ||
| 259 | |||
| 233 | (defun seq--drop-list (list n) | 260 | (defun seq--drop-list (list n) |
| 234 | "Optimized version of `seq-drop' for lists." | 261 | "Optimized version of `seq-drop' for lists." |
| 235 | (while (and list (> n 0)) | 262 | (while (and list (> n 0)) |
diff --git a/test/ChangeLog b/test/ChangeLog index 9ae9db3f8fb..f9a54b53420 100644 --- a/test/ChangeLog +++ b/test/ChangeLog | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | 2015-02-02 Nicolas Petton <nicolas@petton.fr> | 1 | 2015-02-06 Nicolas Petton <nicolas@petton.fr> |
| 2 | 2 | ||
| 3 | * automated/seq-tests.el: New test for seq-mapcat. | 3 | * automated/seq-tests.el: New tests for seq-mapcat, seq-partition |
| 4 | and seq-group-by. | ||
| 4 | 5 | ||
| 5 | 2015-02-05 Artur Malabarba <bruce.connor.am@gmail.com> | 6 | 2015-02-05 Artur Malabarba <bruce.connor.am@gmail.com> |
| 6 | 7 | ||
diff --git a/test/automated/seq-tests.el b/test/automated/seq-tests.el index cc89c889675..ecbc0043210 100644 --- a/test/automated/seq-tests.el +++ b/test/automated/seq-tests.el | |||
| @@ -205,5 +205,21 @@ Evaluate BODY for each created sequence. | |||
| 205 | (should (equal (seq-mapcat #'seq-reverse '((3 2 1) (6 5 4)) 'vector) | 205 | (should (equal (seq-mapcat #'seq-reverse '((3 2 1) (6 5 4)) 'vector) |
| 206 | '[1 2 3 4 5 6]))) | 206 | '[1 2 3 4 5 6]))) |
| 207 | 207 | ||
| 208 | (ert-deftest test-seq-partition () | ||
| 209 | (should (same-contents-p (seq-partition '(0 1 2 3 4 5 6 7) 3) | ||
| 210 | '((0 1 2) (3 4 5) (6 7)))) | ||
| 211 | (should (same-contents-p (seq-partition '[0 1 2 3 4 5 6 7] 3) | ||
| 212 | '([0 1 2] [3 4 5] [6 7]))) | ||
| 213 | (should (same-contents-p (seq-partition "Hello world" 2) | ||
| 214 | '("He" "ll" "o " "wo" "rl" "d"))) | ||
| 215 | (should (equal (seq-partition '() 2) '())) | ||
| 216 | (should (equal (seq-partition '(1 2 3) -1) '()))) | ||
| 217 | |||
| 218 | (ert-deftest test-seq-group-by () | ||
| 219 | (should (equal (seq-group-by #'test-sequences-oddp [1 2 3 4]) | ||
| 220 | '((t 3 1) (nil 4 2)))) | ||
| 221 | (should (equal (seq-group-by #'car '((a 1) (b 3) (c 4) (a 2))) | ||
| 222 | '((a (a 2) (a 1)) (b (b 3)) (c (c 4)))))) | ||
| 223 | |||
| 208 | (provide 'seq-tests) | 224 | (provide 'seq-tests) |
| 209 | ;;; seq-tests.el ends here | 225 | ;;; seq-tests.el ends here |