branch: externals/dash
commit 166bccdd6171f1f732c85a3e18434c8ee6e0ccb3
Author: Matus Goljer <[email protected]>
Commit: Matus Goljer <[email protected]>
Add -tree-map-nodes
---
README.md | 15 +++++++++++++++
dash.el | 18 ++++++++++++++++++
dev/examples.el | 8 ++++++++
3 files changed, 41 insertions(+), 0 deletions(-)
diff --git a/README.md b/README.md
index a6ce378..2e58b9d 100644
--- a/README.md
+++ b/README.md
@@ -193,6 +193,7 @@ Functions pretending lists are trees.
* [-tree-seq](#-tree-seq-branch-children-tree) `(branch children tree)`
* [-tree-map](#-tree-map-fn-tree) `(fn tree)`
+* [-tree-map-nodes](#-tree-map-nodes-pred-fun-tree) `(pred fun tree)`
* [-tree-reduce](#-tree-reduce-fn-tree) `(fn tree)`
* [-tree-reduce-from](#-tree-reduce-from-fn-init-value-tree) `(fn init-value
tree)`
* [-tree-mapreduce](#-tree-mapreduce-fn-folder-tree) `(fn folder tree)`
@@ -1491,6 +1492,20 @@ Apply `fn` to each element of `tree` while preserving
the tree structure.
(--tree-map (length it) '("<body>" ("<p>" "text" "</p>") "</body>")) ;; => '(6
(3 4 4) 7)
```
+#### -tree-map-nodes `(pred fun tree)`
+
+Call `fun` on each node of `tree` that satisfies `pred`.
+
+If `pred` returns nil, continue descending down this node. If `pred`
+returns non-nil, apply `fun` to this node and do not descend
+further.
+
+```cl
+(-tree-map-nodes 'vectorp (lambda (x) (-sum (append x nil))) '(1 [2 3] 4 (5 [6
7] 8))) ;; => '(1 5 4 (5 13 8))
+(-tree-map-nodes 'keywordp (lambda (x) (symbol-name x)) '(1 :foo 4 ((5 6 :bar)
:baz 8))) ;; => '(1 ":foo" 4 ((5 6 ":bar") ":baz" 8))
+(--tree-map-nodes (eq (car-safe it) 'add-mode) (-concat it (list :mode
'emacs-lisp-mode)) '(with-mode emacs-lisp-mode (foo bar) (add-mode a b) (baz
(add-mode c d)))) ;; => '(with-mode emacs-lisp-mode (foo bar) (add-mode a b
:mode emacs-lisp-mode) (baz (add-mode c d :mode emacs-lisp-mode)))
+```
+
#### -tree-reduce `(fn tree)`
Use `fn` to reduce elements of list `tree`.
diff --git a/dash.el b/dash.el
index 8e72182..43e0349 100644
--- a/dash.el
+++ b/dash.el
@@ -1508,6 +1508,21 @@ See `-reduce-r' for how exactly are lists of zero or one
element handled."
(declare (debug (form form)))
`(-tree-reduce (lambda (it acc) ,form) ,tree))
+(defun -tree-map-nodes (pred fun tree)
+ "Call FUN on each node of TREE that satisfies PRED.
+
+If PRED returns nil, continue descending down this node. If PRED
+returns non-nil, apply FUN to this node and do not descend
+further."
+ (if (funcall pred tree)
+ (funcall fun tree)
+ (if (listp tree)
+ (-map (lambda (x) (-tree-map-nodes pred fun x)) tree)
+ tree)))
+
+(defmacro --tree-map-nodes (pred form tree)
+ "Anaphoric form of `-tree-map-nodes'."
+ `(-tree-map-nodes (lambda (it) ,pred) (lambda (it) ,form) ,tree))
(defun -tree-seq (branch children tree)
"Return a sequence of the nodes in TREE, in depth-first search order.
@@ -1527,6 +1542,7 @@ Non-branch nodes are simply copied."
(defmacro --tree-seq (branch children tree)
"Anaphoric form of `-tree-seq'."
`(-tree-seq (lambda (it) ,branch) (lambda (it) ,children) ,tree))
+
(defun -clone (list)
"Create a deep copy of LIST.
The new list has the same elements and structure but all cons are
@@ -1730,6 +1746,8 @@ structure such as plist or alist."
"--tree-reduce"
"-tree-seq"
"--tree-seq"
+ "-tree-map-nodes"
+ "--tree-map-nodes"
"-clone"
"-rpartial"
"-juxt"
diff --git a/dev/examples.el b/dev/examples.el
index 2eebe59..fba6639 100644
--- a/dev/examples.el
+++ b/dev/examples.el
@@ -586,6 +586,14 @@ new list."
(--tree-map 1 '(1 2 (3 4) (5 6))) => '(1 1 (1 1) (1 1))
(--tree-map (cdr it) '((1 . 2) (3 . 4) (5 . 6))) => '(2 4 6))
+ (defexamples -tree-map-nodes
+ (-tree-map-nodes 'vectorp (lambda (x) (-sum (append x nil))) '(1 [2 3] 4
(5 [6 7] 8))) => '(1 5 4 (5 13 8))
+ (-tree-map-nodes 'keywordp (lambda (x) (symbol-name x)) '(1 :foo 4 ((5 6
:bar) :baz 8))) => '(1 ":foo" 4 ((5 6 ":bar") ":baz" 8))
+ (--tree-map-nodes
+ (eq (car-safe it) 'add-mode)
+ (-concat it (list :mode 'emacs-lisp-mode))
+ '(with-mode emacs-lisp-mode (foo bar) (add-mode a b) (baz (add-mode c
d)))) => '(with-mode emacs-lisp-mode (foo bar) (add-mode a b :mode
emacs-lisp-mode) (baz (add-mode c d :mode emacs-lisp-mode))))
+
(defexamples -tree-reduce
(-tree-reduce '+ '(1 (2 3) (4 5))) => 15
(-tree-reduce 'concat '("strings" (" on" " various") ((" levels")))) =>
"strings on various levels"