branch: externals/dash commit f5264dbd9fa1c662740c507c54a6b7b9c162539c Merge: abff641 6bdcfa5 Author: Magnar Sveen <magn...@gmail.com> Commit: Magnar Sveen <magn...@gmail.com>
Merge pull request #77 from Fuco1/split-when Add -split-on, -split-when --- README.md | 35 +++++++++++++++++++++++++++++++++++ dash.el | 38 ++++++++++++++++++++++++++++++++++++++ dev/examples.el | 19 +++++++++++++++++++ 3 files changed, 92 insertions(+), 0 deletions(-) diff --git a/README.md b/README.md index bd5a298..797fd1f 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,8 @@ Operations dual to reductions, building lists from seed value rather than consum * [-split-at](#-split-at-n-list) `(n list)` * [-split-with](#-split-with-pred-list) `(pred list)` +* [-split-on](#-split-on-item-list) `(item list)` +* [-split-when](#-split-when-fn-list) `(fn list)` * [-separate](#-separate-pred-list) `(pred list)` * [-partition](#-partition-n-list) `(n list)` * [-partition-all-in-steps](#-partition-all-in-steps-n-step-list) `(n step list)` @@ -739,6 +741,39 @@ Returns a list of ((-take-while `pred` `list`) (-drop-while `pred` `list`)), in (--split-with (< it 4) '(1 2 3 4 3 2 1)) ;; => '((1 2 3) (4 3 2 1)) ``` +#### -split-on `(item list)` + +Split the `list` each time `item` is found. + +Unlike `-partition-by`, the `item` is discarded from the results. +Empty lists are also removed from the result. + +Comparison is done by `equal`. + +See also `-split-when`. + +```cl +(-split-on '| '(Nil | Leaf a | Node [Tree a])) ;; => '((Nil) (Leaf a) (Node [Tree a])) +(-split-on ':endgroup '("a" "b" :endgroup "c" :endgroup "d" "e")) ;; => '(("a" "b") ("c") ("d" "e")) +(-split-on ':endgroup '("a" "b" :endgroup :endgroup "d" "e")) ;; => '(("a" "b") ("d" "e")) +``` + +#### -split-when `(fn list)` + +Split the `list` on each element where `fn` returns non-nil. + +Unlike `-partition-by`, the "matched" element is discarded from +the results. Empty lists are also removed from the result. + +This function can be thought of as a generalization of +`split-string`. + +```cl +(-split-when 'even? '(1 2 3 4 5 6)) ;; => '((1) (3) (5)) +(-split-when 'even? '(1 2 3 4 6 8 9)) ;; => '((1) (3) (9)) +(--split-when (memq it '(&optional &rest)) '(a b &optional c d &rest args)) ;; => '((a b) (c d) (args)) +``` + #### -separate `(pred list)` Returns a list of ((-filter `pred` `list`) (-remove `pred` `list`)), in one pass through the list. diff --git a/dash.el b/dash.el index c7fd82d..6362e42 100644 --- a/dash.el +++ b/dash.el @@ -560,6 +560,41 @@ from INDICES." "Returns a list of ((-take-while PRED LIST) (-drop-while PRED LIST)), in no more than one pass through the list." (--split-with (funcall pred it) list)) +(defmacro -split-on (item list) + "Split the LIST each time ITEM is found. + +Unlike `-partition-by', the ITEM is discarded from the results. +Empty lists are also removed from the result. + +Comparison is done by `equal'. + +See also `-split-when'." + (declare (debug (form form))) + `(-split-when (lambda (it) (equal it ,item)) ,list)) + +(defmacro --split-when (form list) + "Anaphoric version of `-split-when'." + (declare (debug (sexp form))) + `(-split-when (lambda (it) ,form) ,list)) + +(defun -split-when (fn list) + "Split the LIST on each element where FN returns non-nil. + +Unlike `-partition-by', the \"matched\" element is discarded from +the results. Empty lists are also removed from the result. + +This function can be thought of as a generalization of +`split-string'." + (let (r s) + (while list + (if (not (funcall fn (car list))) + (push (car list) s) + (when s (push (nreverse s) r)) + (setq s nil)) + (!cdr list)) + (when s (push (nreverse s) r)) + (nreverse r))) + (defmacro --separate (form list) "Anaphoric form of `-separate'." (declare (debug (sexp form))) @@ -1371,6 +1406,9 @@ structure such as plist or alist." "-remove-at-indices" "-split-with" "--split-with" + "-split-on" + "-split-when" + "--split-when" "-separate" "--separate" "-partition-all-in-steps" diff --git a/dev/examples.el b/dev/examples.el index 7b6d4dc..0c4751a 100644 --- a/dev/examples.el +++ b/dev/examples.el @@ -277,6 +277,25 @@ (-split-with 'even? '(2 4 5 6)) => '((2 4) (5 6)) (--split-with (< it 4) '(1 2 3 4 3 2 1)) => '((1 2 3) (4 3 2 1))) + (defexamples -split-on + (-split-on '| '(Nil | Leaf a | Node [Tree a])) => '((Nil) (Leaf a) (Node [Tree a])) + (-split-on ':endgroup '("a" "b" :endgroup "c" :endgroup "d" "e")) => '(("a" "b") ("c") ("d" "e")) + (-split-on ':endgroup '("a" "b" :endgroup :endgroup "d" "e")) => '(("a" "b") ("d" "e")) + (-split-on ':endgroup '("a" "b" :endgroup "c" :endgroup)) => '(("a" "b") ("c")) + (-split-on ':endgroup '("a" "b" :endgroup :endgroup :endgroup "d" "e")) => '(("a" "b") ("d" "e")) + (-split-on ':endgroup '(:endgroup "c" :endgroup "d" "e")) => '(("c") ("d" "e")) + (-split-on '| '(Nil | | Node [Tree a])) => '((Nil) (Node [Tree a]))) + + (defexamples -split-when + (-split-when 'even? '(1 2 3 4 5 6)) => '((1) (3) (5)) + (-split-when 'even? '(1 2 3 4 6 8 9)) => '((1) (3) (9)) + (--split-when (memq it '(&optional &rest)) '(a b &optional c d &rest args)) => '((a b) (c d) (args)) + (-split-when 'even? '(1 2 3 5 6)) => '((1) (3 5)) + (-split-when 'even? '(1 2 3 5)) => '((1) (3 5)) + (-split-when 'even? '(1 3 4 5 6)) => '((1 3) (5)) + (-split-when 'even? '(1 2 3 4 5 6 8 10)) => '((1) (3) (5)) + (-split-when 'even? '(1 2 3 5 7 6)) => '((1) (3 5 7))) + (defexamples -separate (-separate (lambda (num) (= 0 (% num 2))) '(1 2 3 4 5 6 7)) => '((2 4 6) (1 3 5 7)) (--separate (< it 5) '(3 7 5 9 3 2 1 4 6)) => '((3 3 2 1 4) (7 5 9 6))