diff --git a/dash.el b/dash.el index a924424..5b2b3b3 100644 --- a/dash.el +++ b/dash.el @@ -331,6 +331,28 @@ Returns `nil` both if all items match the predicate, and if none of the items ma (defalias '-only-some-p '-only-some?) (defalias '--only-some-p '--only-some?) +(defun -slice (list from &optional to) + "Return copy of LIST, starting from index FROM to index TO. +FROM or TO may be negative." + (let ((length (length list)) + (new-list nil) + (index 0)) + ;; to defaults to the end of the list + (setq to (or to length)) + ;; handle negative indices + (when (< from 0) + (setq from (mod from length))) + (when (< to 0) + (setq to (mod to length))) + + ;; iterate through the list, keeping the elements we want + (while (< index to) + (when (>= index from) + (!cons (car list) new-list)) + (!cdr list) + (setq index (1+ index))) + (nreverse new-list))) + (defun -take (n list) "Returns a new list of the first N items in LIST, or all items if there are fewer than N." (let (result) diff --git a/dev/examples.el b/dev/examples.el index 2fb37d9..40a1ed3 100644 --- a/dev/examples.el +++ b/dev/examples.el @@ -122,6 +122,11 @@ (-repeat 0 :a) => nil (-repeat -1 :a) => nil) +(defexamples -slice + (-slice '(1 2 3 4 5) 1) => '(2 3 4 5) + (-slice '(1 2 3 4 5) 0 3) => '(1 2 3) + (-slice '(1 2 3 4 5) 1 -1) => '(2 3 4)) + (defexamples -take (-take 3 '(1 2 3 4 5)) => '(1 2 3) (-take 17 '(1 2 3 4 5)) => '(1 2 3 4 5))