about summary refs log tree commit diff
path: root/configs/shared/.emacs.d/wpc/alist.el
diff options
context:
space:
mode:
authorWilliam Carroll <wpcarro@gmail.com>2019-12-24T12·28+0000
committerWilliam Carroll <wpcarro@gmail.com>2020-01-06T15·25+0000
commit837a74f10f008e61d20c6307520bca38d9c9e89c (patch)
treeb667026aaf030fda445d4317ab6b183426d4ac3b /configs/shared/.emacs.d/wpc/alist.el
parent9d20c1b8945aee93a438fb85ee70330079ace6e8 (diff)
Support alist/{find,map-keys,map-values} and tests
Supporting iterable / enumerable functions for alists.
Diffstat (limited to 'configs/shared/.emacs.d/wpc/alist.el')
-rw-r--r--configs/shared/.emacs.d/wpc/alist.el51
1 files changed, 50 insertions, 1 deletions
diff --git a/configs/shared/.emacs.d/wpc/alist.el b/configs/shared/.emacs.d/wpc/alist.el
index da0ce68b8f75..c43df7823b32 100644
--- a/configs/shared/.emacs.d/wpc/alist.el
+++ b/configs/shared/.emacs.d/wpc/alist.el
@@ -85,6 +85,17 @@
 
 ;; TODO: Consider wrapping all of this with `(cl-defstruct alist xs)'.
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Constants
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defconst alist/enable-tests? t
+  "When t, run the test suite.")
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Library
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
 (defun alist/new ()
   "Return a new, empty alist."
   '())
@@ -181,8 +192,29 @@ Mutative variant of `alist/delete'."
   "Return the number of entries in XS."
   (length xs))
 
+;; TODO: Should I support `alist/find-key' and `alist/find-value' variants?
+(defun alist/find (p xs)
+  "Apply a predicate fn, P, to each key and value in XS and return the key of
+  the first element that returns t."
+  (let ((result (list/find (lambda (x) (funcall p (car x) (cdr x))) xs)))
+    (if result
+        (car result)
+      nil)))
+
+(defun alist/map-keys (f xs)
+  "Call F on the values in XS, returning a new alist."
+  (list/map (lambda (x)
+              `(,(funcall f (car x)) . ,(cdr x)))
+            xs))
+
+(defun alist/map-values (f xs)
+  "Call F on the values in XS, returning a new alist."
+  (list/map (lambda (x)
+              `(,(car x) . ,(funcall f (cdr x))))
+            xs))
+
 (defun alist/reduce (acc f xs)
-  "Return a new alist by calling, F, on k v and ACC from XS.
+  "Return a new alist by calling F on k v and ACC from XS.
 F should return a tuple.  See tuple.el for more information."
   (->> (alist/keys xs)
        (list/reduce acc
@@ -219,7 +251,24 @@ In this case, the last writer wins, which is B."
    (alist/dedupe-entries person)
    (alist/count person)))
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Tests
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(when alist/enable-tests?
+  (prelude/assert
+   (equal '((2 . one)
+            (3 . two))
+          (alist/map-keys #'1+
+                          '((1 . one)
+                            (2 . two)))))
+  (prelude/assert
+   (equal '((one . 2)
+            (two . 3))
+          (alist/map-values #'1+
+                            '((one . 1)
+                              (two . 2))))))
+
 
 ;; TODO: Support test cases for the entire API.