Merge pull request #88 from steventlamb/topic/zip_cycle_pad

Topic/zip cycle pad
master
Magnar Sveen 12 years ago
commit fb51f8f326
  1. 49
      README.md
  2. 41
      dash.el
  3. 22
      dev/examples.el
  4. 2
      readme-template.md

@ -134,6 +134,10 @@ Operations dual to reductions, building lists from seed value rather than consum
* [-interleave](#-interleave-rest-lists) `(&rest lists)`
* [-zip-with](#-zip-with-fn-list1-list2) `(fn list1 list2)`
* [-zip](#-zip-rest-lists) `(&rest lists)`
* [-zip-fill](#-zip-fill-fill-value-rest-lists) `(fill-value &rest lists)`
* [-cycle](#-cycle-list) `(list)`
* [-pad](#-pad-fill-value-rest-lists) `(fill-value &rest lists)`
* [-annotate](#-annotate-fn-list) `(fn list)`
* [-first](#-first-pred-list) `(pred list)`
* [-last](#-last-pred-list) `(pred list)`
* [-first-item](#-first-item-list) `(list)`
@ -1103,6 +1107,49 @@ of cons cells. Otherwise, return the groupings as a list of lists.
(-zip '(1 2 3 4) '(4 5 6)) ;; => '((1 . 4) (2 . 5) (3 . 6))
```
#### -zip-fill `(fill-value &rest lists)`
Zip `lists`, with `fill-value` padded onto the shorter lists. The
lengths of the returned groupings are equal to the length of the
longest input list.
```cl
(-zip-fill 0 '(1 2 3 4 5) '(6 7 8 9)) ;; => '((1 . 6) (2 . 7) (3 . 8) (4 . 9) (5 . 0))
```
#### -cycle `(list)`
Returns an infinite copy of `list` that will cycle through the
elements and repeat from the beginning.
```cl
(-take 5 (-cycle '(1 2 3))) ;; => '(1 2 3 1 2)
(-take 7 (-cycle '(1 "and" 3))) ;; => '(1 "and" 3 1 "and" 3 1)
(-zip (-cycle '(1 2 3)) '(1 2)) ;; => '((1 . 1) (2 . 2))
```
#### -pad `(fill-value &rest lists)`
Appends `fill-value` to the end of each list in `lists` such that they
will all have the same length.
```cl
(-pad 0 '()) ;; => '(nil)
(-pad 0 '(1)) ;; => '((1))
(-pad 0 '(1 2 3) '(4 5)) ;; => '((1 2 3) (4 5 0))
```
#### -annotate `(fn list)`
Returns a list of cons cells where each cell is `fn` applied to each
element of `list` paired with the unmodified element of `list`.
```cl
(-annotate '1+ '(1 2 3)) ;; => '((2 . 1) (3 . 2) (4 . 3))
(-annotate 'length '(("h" "e" "l" "l" "o") ("hello" "world"))) ;; => '((5 "h" "e" "l" "l" "o") (2 "hello" "world"))
(--annotate (< 1 it) '(0 1 2 3)) ;; => '((nil . 0) (nil . 1) (t . 2) (t . 3))
```
#### -first `(pred list)`
Returns the first x in `list` where (`pred` x) is non-nil, else nil.
@ -1669,7 +1716,7 @@ Change `readme-template.md` or `examples-to-docs.el` instead.
- [Emanuel Evans](https://github.com/shosti) contributed `-if-let`, `-when-let` and `-insert-at`.
- [Johan Andersson](https://github.com/rejeep) contributed `-sum`, `-product` and `-same-items?`
- [Christina Whyte](https://github.com/kurisuwhyte) contributed `-compose`
- [Steve Lamb](https://github.com/steventlamb) contributed an n-ary version of `-zip`
- [Steve Lamb](https://github.com/steventlamb) contributed `-cycle`, `-pad`, `-annotate`, `-zip-fill` and an n-ary version of `-zip`.
Thanks!

@ -803,14 +803,10 @@ groupings are equal to the length of the shortest input list.
If two lists are provided as arguments, return the groupings as a list
of cons cells. Otherwise, return the groupings as a list of lists. "
(let* ((n (-min (-map 'length lists)))
(level-lists (-map (-partial '-take n) lists))
results)
(while (> n 0)
(let ((split-lists (-map (-partial '-split-at 1) level-lists)))
(setq results (cons (-map 'caar split-lists) results))
(setq level-lists (-map 'cadr split-lists))
(setq n (1- n))))
(let (results)
(while (-none? 'null lists)
(setq results (cons (mapcar 'car lists) results))
(setq lists (mapcar 'cdr lists)))
(setq results (nreverse results))
(if (= (length lists) 2)
; to support backward compatability, return
@ -818,6 +814,35 @@ of cons cells. Otherwise, return the groupings as a list of lists. "
(--map (cons (car it) (cadr it)) results)
results)))
(defun -zip-fill (fill-value &rest lists)
"Zip LISTS, with FILL-VALUE padded onto the shorter lists. The
lengths of the returned groupings are equal to the length of the
longest input list."
(apply '-zip (apply '-pad (cons fill-value lists))))
(defun -cycle (list)
"Returns an infinite copy of LIST that will cycle through the
elements and repeat from the beginning."
(let ((newlist (-map 'identity list)))
(nconc newlist newlist)))
(defun -pad (fill-value &rest lists)
"Appends FILL-VALUE to the end of each list in LISTS such that they
will all have the same length."
(let* ((annotations (-annotate 'length lists))
(n (-max (-map 'car annotations))))
(--map (append (cdr it) (-repeat (- n (car it)) fill-value)) annotations)))
(defun -annotate (fn list)
"Returns a list of cons cells where each cell is FN applied to each
element of LIST paired with the unmodified element of LIST."
(-zip (-map fn list) list))
(defmacro --annotate (form list)
"Anaphoric version of `-annotate'."
(declare (debug (form form)))
`(-annotate (lambda (it) ,form) ,list))
(defun -partial (fn &rest args)
"Takes a function FN and fewer than the normal arguments to FN,
and returns a fn that takes a variable number of additional ARGS.

@ -439,6 +439,28 @@
(-zip '(1 2 3) '(4 5 6) '(7 8 9)) => '((1 4 7) (2 5 8) (3 6 9))
(-zip '(1 2) '(3 4 5) '(6)) => '((1 3 6)))
(defexamples -zip-fill
(-zip-fill 0 '(1 2 3 4 5) '(6 7 8 9)) => '((1 . 6) (2 . 7) (3 . 8) (4 . 9) (5 . 0)))
(defexamples -cycle
(-take 5 (-cycle '(1 2 3))) => '(1 2 3 1 2)
(-take 7 (-cycle '(1 "and" 3))) => '(1 "and" 3 1 "and" 3 1)
(-zip (-cycle '(1 2 3)) '(1 2)) => '((1 . 1) (2 . 2))
(-zip-with 'cons (-cycle '(1 2 3)) '(1 2)) => '((1 . 1) (2 . 2))
(-map (-partial '-take 5) (-split-at 5 (-cycle '(1 2 3)))) => '((1 2 3 1 2) (3 1 2 3 1)))
(defexamples -pad
(-pad 0 '()) => '(())
(-pad 0 '(1)) => '((1))
(-pad 0 '(1 2 3) '(4 5)) => '((1 2 3) (4 5 0))
(-pad nil '(1 2 3) '(4 5) '(6 7 8 9 10)) => '((1 2 3 nil nil) (4 5 nil nil nil) (6 7 8 9 10))
(-pad 0 '(1 2) '(3 4)) => '((1 2) (3 4)))
(defexamples -annotate
(-annotate '1+ '(1 2 3)) => '((2 . 1) (3 . 2) (4 . 3))
(-annotate 'length '(("h" "e" "l" "l" "o") ("hello" "world"))) => '((5 . ("h" "e" "l" "l" "o")) (2 . ("hello" "world")))
(--annotate (< 1 it) '(0 1 2 3)) => '((nil . 0) (nil . 1) (t . 2) (t . 3)))
(defexamples -first
(-first 'even? '(1 2 3)) => 2
(-first 'even? '(1 3 5)) => nil

@ -174,7 +174,7 @@ Change `readme-template.md` or `examples-to-docs.el` instead.
- [Emanuel Evans](https://github.com/shosti) contributed `-if-let`, `-when-let` and `-insert-at`.
- [Johan Andersson](https://github.com/rejeep) contributed `-sum`, `-product` and `-same-items?`
- [Christina Whyte](https://github.com/kurisuwhyte) contributed `-compose`
- [Steve Lamb](https://github.com/steventlamb) contributed an n-ary version of `-zip`
- [Steve Lamb](https://github.com/steventlamb) contributed `-cycle`, `-pad`, `-annotate`, `-zip-fill` and an n-ary version of `-zip`.
Thanks!

Loading…
Cancel
Save