summary refs log tree commit diff
diff options
context:
space:
mode:
authorArun Isaac2022-08-14 20:04:01 +0530
committerArun Isaac2022-08-14 20:04:01 +0530
commit3d596d98948b89299ed7a793c5158fb7c537e7f8 (patch)
tree0de130977c8f778da69ebf16b292908542226acb
parent6a47089094387178685444218a4ad55874dd323d (diff)
downloadennum-3d596d98948b89299ed7a793c5158fb7c537e7f8.tar.gz
ennum-3d596d98948b89299ed7a793c5158fb7c537e7f8.tar.lz
ennum-3d596d98948b89299ed7a793c5158fb7c537e7f8.zip
Rewrite many to many grouping using functional setters.
* ennum.el (ennum-assoc-delete, ennum-assoc-set, ennum-assoc-prepend):
New functions.
* ennum.el (ennum-many-to-many-group-by): Use ennum-assoc-append
instead of mutating the result association list.
-rw-r--r--ennum.el42
1 files changed, 31 insertions, 11 deletions
diff --git a/ennum.el b/ennum.el
index d8a54fb..fa0e794 100644
--- a/ennum.el
+++ b/ennum.el
@@ -612,21 +612,41 @@ value of the last form in BODY."
          (progn ,@body)
        (delete-directory ,temporary-directory t))))
 
+(defun ennum-assoc-delete (key alist)
+  "Delete KEY from ALIST.
+
+Delete all occurrences of KEY in ALIST. This function is purely
+functional. ALIST is not mutated."
+  (seq-remove (pcase-lambda (`(,entry-key . ,_))
+                (equal entry-key key))
+              alist))
+
+(defun ennum-assoc-set (key value alist)
+  "Associate KEY with VALUE in ALIST.
+
+This function is purely functional. ALIST is not mutated. Keys
+are compared using `equal'."
+  (cl-acons key value (ennum-assoc-delete key alist)))
+
+(defun ennum-assoc-prepend (key value alist)
+  "Prepend VALUE to that associated with KEY in ALIST.
+
+This function is purely funcion. ALIST is not mutated."
+  (ennum-assoc-set key
+                   (cons value (map-elt alist key nil 'equal))
+                   alist))
+
 (defun ennum-many-to-many-group-by (function sequence)
   "Apply FUNCTION to each element of SEQUENCE.
 Separate the elements of SEQUENCE into an alist using the results
 as keys. Keys are compared using `equal'."
-  (seq-reduce
-   (lambda (result element)
-     (seq-do
-      (lambda (key)
-        (map-put result key
-                 (cons element (map-elt result key nil 'equal))
-                 'equal))
-      (funcall function element))
-     result)
-   (seq-reverse sequence)
-   nil))
+  (seq-reduce (lambda (result element)
+                (seq-reduce (lambda (result key)
+                              (ennum-assoc-prepend key element result))
+                            (funcall function element)
+                            result))
+              (seq-reverse sequence)
+              nil))
 
 (defun ennum-publish ()
   (interactive)