]> git.eshelyaron.com Git - emacs.git/commitdiff
Add seq-partition and seq-group-by
authorNicolas Petton <nicolas@petton.fr>
Fri, 6 Feb 2015 14:55:57 +0000 (15:55 +0100)
committerNicolas Petton <nicolas@petton.fr>
Fri, 6 Feb 2015 14:55:57 +0000 (15:55 +0100)
* 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

lisp/ChangeLog
lisp/emacs-lisp/seq.el
test/ChangeLog
test/automated/seq-tests.el

index aa58c5349aaa9b86fe5472558e87fb3d0ee354b9..0cd2a4d04e85acd92888efdfb4786acf2c75bb8f 100644 (file)
@@ -1,6 +1,6 @@
 2015-02-06  Nicolas Petton <nicolas@petton.fr>
 
-       * emacs-lisp/seq.el (seq-mapcat): New function.
+       * emacs-lisp/seq.el (seq-mapcat, seq-partition, seq-group-by): New functions.
 
 2015-02-06  Artur Malabarba  <bruce.connor.am@gmail.com>
 
index bd234a3b55ae70822f794c11b0995ea2e4934c94..cd45989eca8627d191c3447b32b1636ee78ffa71 100644 (file)
@@ -230,6 +230,33 @@ The result is a sequence of type TYPE, or a list if TYPE is nil."
   (apply #'seq-concatenate (or type 'list)
          (seq-map function seq)))
 
+(defun seq-partition (seq n)
+  "Return a list of the elements of SEQ grouped into sub-sequences of length N.
+The last sequence may contain less than N elements.  If N is a
+negative integer or 0, nil is returned."
+  (unless (< n 1)
+    (let ((result '()))
+      (while (not (seq-empty-p seq))
+        (push (seq-take seq n) result)
+        (setq seq (seq-drop seq n)))
+      (nreverse result))))
+
+(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
+keys.  Keys are compared using `equal'."
+  (nreverse
+   (seq-reduce
+    (lambda (acc elt)
+      (let* ((key (funcall function elt))
+             (cell (assoc key acc)))
+        (if cell
+            (setcdr cell (push elt (cdr cell)))
+          (push (list key elt) acc))
+        acc))
+    seq
+    nil)))
+
 (defun seq--drop-list (list n)
   "Optimized version of `seq-drop' for lists."
   (while (and list (> n 0))
index 9ae9db3f8fb99d7a03b8dd479d5c1aa7a6d7e0b5..f9a54b53420a7ec81b5eeefba124e0923806eb18 100644 (file)
@@ -1,6 +1,7 @@
-2015-02-02 Nicolas Petton <nicolas@petton.fr>
+2015-02-06 Nicolas Petton <nicolas@petton.fr>
 
-       * automated/seq-tests.el: New test for seq-mapcat.
+       * automated/seq-tests.el: New tests for seq-mapcat, seq-partition
+       and seq-group-by.
 
 2015-02-05  Artur Malabarba  <bruce.connor.am@gmail.com>
 
index cc89c889675d51c9a600022e1a277b7aa278a999..ecbc004321010414d21845e95ec3bdee88567411 100644 (file)
@@ -205,5 +205,21 @@ Evaluate BODY for each created sequence.
   (should (equal (seq-mapcat #'seq-reverse '((3 2 1) (6 5 4)) 'vector)
                  '[1 2 3 4 5 6])))
 
+(ert-deftest test-seq-partition ()
+  (should (same-contents-p (seq-partition '(0 1 2 3 4 5 6 7) 3)
+                           '((0 1 2) (3 4 5) (6 7))))
+  (should (same-contents-p (seq-partition '[0 1 2 3 4 5 6 7] 3)
+                           '([0 1 2] [3 4 5] [6 7])))
+  (should (same-contents-p (seq-partition "Hello world" 2)
+                           '("He" "ll" "o " "wo" "rl" "d")))
+  (should (equal (seq-partition '() 2) '()))
+  (should (equal (seq-partition '(1 2 3) -1) '())))
+
+(ert-deftest test-seq-group-by ()
+  (should (equal (seq-group-by #'test-sequences-oddp [1 2 3 4])
+                 '((t 3 1) (nil 4 2))))
+  (should (equal (seq-group-by #'car '((a 1) (b 3) (c 4) (a 2)))
+                 '((a (a 2) (a 1)) (b (b 3)) (c (c 4))))))
+
 (provide 'seq-tests)
 ;;; seq-tests.el ends here