Add -iterate, -unfold

master
Matus Goljer 12 years ago
parent 4098ea0f9d
commit b0758469ce
  1. 47
      README.md
  2. 43
      dash.el
  3. 13
      dev/examples.el

@ -72,6 +72,14 @@ Include this in your emacs settings to get syntax highlighting:
* [-max](#-max-list) `(list)`
* [-max-by](#-max-by-comparator-list) `(comparator list)`
### Unfolding
Operations dual to reductions, building lists from seed value rather than consuming a list to produce a single value.
* [-iterate](#-iterate-fun-init-n) `(fun init n)`
* [-unfold](#-unfold-fun-seed) `(fun seed)`
### Predicates
* [-any?](#-any-pred-list) `(pred list)`
@ -564,6 +572,45 @@ comparing them.
```
## Unfolding
Operations dual to reductions, building lists from seed value rather than consuming a list to produce a single value.
#### -iterate `(fun init n)`
Return a list of iterated applications of `fun` to `init`.
This means a list of form:
'(init (fun init) (fun (fun init)) ...)
`n` is the length of the returned list.
```cl
(-iterate '1+ 1 10) ;; => '(1 2 3 4 5 6 7 8 9 10)
(-iterate (lambda (x) (+ x x)) 2 5) ;; => '(2 4 8 16 32)
(--iterate (* it it) 2 5) ;; => '(2 4 16 256 65536)
```
#### -unfold `(fun seed)`
Build a list from `seed` using `fun`.
This is "dual" operation to `-reduce-r`: while -reduce-r
consumes a list to produce a single value, `-unfold` takes a
seed value and builds a (potentially infinite!) list.
`fun` should return `nil` to stop the generating process, or a
cons (`a` . `b`), where `a` will be prepended to the result and `b` is
the new seed.
```cl
(-unfold (lambda (x) (unless (= x 0) (cons x (1- x)))) 10) ;; => '(10 9 8 7 6 5 4 3 2 1)
(--unfold (when it (cons it (cdr it))) '(1 2 3 4)) ;; => '((1 2 3 4) (2 3 4) (3 4) (4))
(--unfold (when it (cons it (butlast it))) '(1 2 3 4)) ;; => '((1 2 3 4) (1 2 3) (1 2) (1))
```
## Predicates
#### -any? `(pred list)`

@ -1089,6 +1089,45 @@ The items for the comparator form are exposed as \"it\" and \"other\"."
(declare (debug (sexp form)))
`(-min-by (lambda (it other) ,form) ,list))
(defun -iterate (fun init n)
"Return a list of iterated applications of FUN to INIT.
This means a list of form:
'(init (fun init) (fun (fun init)) ...)
N is the length of the returned list."
(if (= n 0) nil
(let ((r (list init)))
(--dotimes (1- n)
(push (funcall fun (car r)) r))
(nreverse r))))
(defmacro --iterate (form init n)
"Anaphoric version of `-iterate'."
(declare (debug (sexp form form)))
`(-iterate (lambda (it) ,form) ,init ,n))
(defun -unfold (fun seed)
"Build a list from SEED using FUN.
This is \"dual\" operation to `-reduce-r': while -reduce-r
consumes a list to produce a single value, `-unfold' takes a
seed value and builds a (potentially infinite!) list.
FUN should return `nil' to stop the generating process, or a
cons (A . B), where A will be prepended to the result and B is
the new seed."
(let ((last (funcall fun seed)) r)
(while last
(push (car last) r)
(setq last (funcall fun (cdr last))))
(nreverse r)))
(defmacro --unfold (form seed)
"Anaphoric version of `-unfold'."
(declare (debug (sexp form)))
`(-unfold (lambda (it) ,form) ,seed))
(defun -cons-pair? (con)
"Return non-nil if CON is true cons pair.
That is (A . B) where B is not a list."
@ -1367,6 +1406,10 @@ structure such as plist or alist."
"--max-by"
"-min-by"
"--min-by"
"-iterate"
"--iterate"
"-unfold"
"--unfold"
"-cons-pair?"
"-cons-to-list"
"-value-to-list"

@ -199,6 +199,19 @@
(--max-by (> (car it) (car other)) '((1 2 3) (2) (3 2))) => '(3 2)
(--max-by (> (length it) (length other)) '((1 2 3) (2) (3 2))) => '(1 2 3)))
(def-example-group "Unfolding"
"Operations dual to reductions, building lists from seed value rather than consuming a list to produce a single value."
(defexamples -iterate
(-iterate '1+ 1 10) => '(1 2 3 4 5 6 7 8 9 10)
(-iterate (lambda (x) (+ x x)) 2 5) => '(2 4 8 16 32)
(--iterate (* it it) 2 5) => '(2 4 16 256 65536))
(defexamples -unfold
(-unfold (lambda (x) (unless (= x 0) (cons x (1- x)))) 10) => '(10 9 8 7 6 5 4 3 2 1)
(--unfold (when it (cons it (cdr it))) '(1 2 3 4)) => '((1 2 3 4) (2 3 4) (3 4) (4))
(--unfold (when it (cons it (butlast it))) '(1 2 3 4)) => '((1 2 3 4) (1 2 3) (1 2) (1))))
(def-example-group "Predicates" nil
(defexamples -any?
(-any? 'even? '(1 2 3)) => t

Loading…
Cancel
Save