emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/dash 3044e83 129/439: Merge pull request #8 from tkf/gr


From: Phillip Lord
Subject: [elpa] externals/dash 3044e83 129/439: Merge pull request #8 from tkf/group-by
Date: Tue, 04 Aug 2015 20:27:09 +0000

branch: externals/dash
commit 3044e83308c0be9c1a1dd3f396cf2190406ac1f3
Merge: 8f91ec8 a23aa4b
Author: Magnar Sveen <address@hidden>
Commit: Magnar Sveen <address@hidden>

    Merge pull request #8 from tkf/group-by
    
    Add -group-by
---
 README.md   |   12 ++++++++++++
 dash.el     |   32 ++++++++++++++++++++++++++++++++
 examples.el |    5 +++++
 3 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/README.md b/README.md
index b69d9ba..3ef011b 100644
--- a/README.md
+++ b/README.md
@@ -39,6 +39,7 @@ Or you can just dump `dash.el` in your load path somewhere.
 * [-partition](#-partition-n-list) `(n list)`
 * [-partition-all](#-partition-all-n-list) `(n list)`
 * [-partition-by](#-partition-by-fn-list) `(fn list)`
+* [-group-by](#-group-by-fn-list) `(fn list)`
 * [-interpose](#-interpose-sep-list) `(sep list)`
 * [-interleave](#-interleave-rest-lists) `(&rest lists)`
 * [-first](#-first-pred-list) `(pred list)`
@@ -375,6 +376,17 @@ Applies `fn` to each value in `list`, splitting it each 
time `fn` returns a new
 (--partition-by (< it 3) '(1 2 3 4 3 2 1)) ;; => '((1 2) (3 4 3) (2 1))
 ```
 
+### -group-by `(fn list)`
+
+Separate `list` into an alist whose keys are `fn` applied to the
+elements of `list`.  Keys are compared by `equal`.
+
+```cl
+(-group-by 'even? '()) ;; => '()
+(-group-by 'even? '(1 1 2 2 2 3 4 6 8)) ;; => '((nil 1 1 3) (t 2 2 2 4 6 8))
+(--group-by (car (split-string it "/")) '("a/b" "c/d" "a/e")) ;; => '(("a" 
"a/b" "a/e") ("c" "c/d"))
+```
+
 ### -interpose `(sep list)`
 
 Returns a new list of all elements in `list` separated by `sep`.
diff --git a/dash.el b/dash.el
index 4103eae..a5e40bb 100644
--- a/dash.el
+++ b/dash.el
@@ -405,6 +405,38 @@ The last group may contain less than N items."
   "Applies FN to each value in LIST, splitting it each time FN returns a new 
value."
   (--partition-by (funcall fn it) list))
 
+(defmacro --group-by (form list)
+  "Anaphoric form of `-group-by'."
+  (let ((l (make-symbol "list"))
+        (v (make-symbol "value"))
+        (k (make-symbol "key"))
+        (r (make-symbol "result")))
+    `(let ((,l ,list)
+           ,r)
+       ;; Convert `list' to an alist and store it in `r'.
+       (while ,l
+         (let* ((,v (car ,l))
+                (it ,v)
+                (,k ,form)
+                (kv (assoc ,k ,r)))
+           (if kv
+               (setcdr kv (cons ,v (cdr kv)))
+             (push (list ,k ,v) ,r))
+           (setq ,l (cdr ,l))))
+       ;; Reverse lists in each group.
+       (let ((rest ,r))
+         (while rest
+           (let ((kv (car rest)))
+             (setcdr kv (nreverse (cdr kv))))
+           (setq rest (cdr rest))))
+       ;; Reverse order of keys.
+       (nreverse ,r))))
+
+(defun -group-by (fn list)
+  "Separate LIST into an alist whose keys are FN applied to the
+elements of LIST.  Keys are compared by `equal'."
+  (--group-by (funcall fn it) list))
+
 (defun -interpose (sep list)
   "Returns a new list of all elements in LIST separated by SEP."
   (let (result)
diff --git a/examples.el b/examples.el
index 8bc0a37..14b38e1 100644
--- a/examples.el
+++ b/examples.el
@@ -150,6 +150,11 @@
   (-partition-by 'even? '(1 1 2 2 2 3 4 6 8)) => '((1 1) (2 2 2) (3) (4 6 8))
   (--partition-by (< it 3) '(1 2 3 4 3 2 1)) => '((1 2) (3 4 3) (2 1)))
 
+(defexamples -group-by
+  (-group-by 'even? '()) => '()
+  (-group-by 'even? '(1 1 2 2 2 3 4 6 8)) => '((nil . (1 1 3)) (t . (2 2 2 4 6 
8)))
+  (--group-by (car (split-string it "/")) '("a/b" "c/d" "a/e")) => '(("a" . 
("a/b" "a/e")) ("c" . ("c/d"))))
+
 (defexamples -interpose
   (-interpose "-" '()) => '()
   (-interpose "-" '("a")) => '("a")



reply via email to

[Prev in Thread] Current Thread [Next in Thread]