[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/dash db45ee7 252/316: Optimize -remove-first a bit
From: |
ELPA Syncer |
Subject: |
[elpa] externals/dash db45ee7 252/316: Optimize -remove-first a bit |
Date: |
Mon, 15 Feb 2021 15:58:11 -0500 (EST) |
branch: externals/dash
commit db45ee715a8f8fcd77cd1888e599509f24ac8f87
Author: Basil L. Contovounesios <contovob@tcd.ie>
Commit: Basil L. Contovounesios <contovob@tcd.ie>
Optimize -remove-first a bit
* dash.el (--remove-first): Open code -remove-first using nconc
instead of -concat for speed. Extend docstring.
(-remove-first): Rewrite in terms of --remove-first. Extend
docstring.
* dev/examples.el (-remove-first): Extend tests.
* README.md:
* dash.texi: Regenerate docs.
---
README.md | 23 +++++++++++++----------
dash.el | 42 ++++++++++++++++++++++++++----------------
dash.texi | 25 ++++++++++++++-----------
dev/examples.el | 17 ++++++++++-------
4 files changed, 63 insertions(+), 44 deletions(-)
diff --git a/README.md b/README.md
index f7e9266..ff51a38 100644
--- a/README.md
+++ b/README.md
@@ -541,16 +541,19 @@ For similar operations, see also
[`-keep`](#-keep-fn-list) and [`-filter`](#-fil
#### -remove-first `(pred list)`
-Return a new list with the first item matching `pred` removed.
-
-Alias: `-reject-first`
-
-See also: [`-remove`](#-remove-pred-list),
[`-map-first`](#-map-first-pred-rep-list)
-
-```el
-(-remove-first 'even? '(1 3 5 4 7 8 10)) ;; => '(1 3 5 7 8 10)
-(-remove-first 'stringp '(1 2 "first" "second" "third")) ;; => '(1 2 "second"
"third")
-(--remove-first (> it 3) '(1 2 3 4 5 6 7 8 9 10)) ;; => '(1 2 3 5 6 7 8 9 10)
+Remove the first item from `list` for which `pred` returns non-nil.
+This is a non-destructive operation, but only the front of `list`
+leading up to the removed item is a copy; the rest is `list``s
+original tail. If no item is removed, then the result is a
+complete copy.
+Alias: `-reject-first`.
+This function's anaphoric counterpart is `--remove-first`.
+See also [`-map-first`](#-map-first-pred-rep-list),
[`-remove-item`](#-remove-item-item-list), and
[`-remove-last`](#-remove-last-pred-list).
+
+```el
+(-remove-first #'natnump '(-2 -1 0 1 2)) ;; => '(-2 -1 1 2)
+(-remove-first #'stringp '(1 2 "first" "second")) ;; => '(1 2 "second")
+(--remove-first (> it 3) '(1 2 3 4 5 6)) ;; => '(1 2 3 5 6)
```
#### -remove-last `(pred list)`
diff --git a/dash.el b/dash.el
index da701ae..3c51812 100644
--- a/dash.el
+++ b/dash.el
@@ -456,24 +456,34 @@ For similar operations, see also `-keep' and `-filter'."
(defalias '-reject '-remove)
(defalias '--reject '--remove)
-(defun -remove-first (pred list)
- "Return a new list with the first item matching PRED removed.
-
-Alias: `-reject-first'
-
-See also: `-remove', `-map-first'"
- (let (front)
- (while (and list (not (funcall pred (car list))))
- (push (car list) front)
- (!cdr list))
- (if list
- (-concat (nreverse front) (cdr list))
- (nreverse front))))
-
(defmacro --remove-first (form list)
- "Anaphoric form of `-remove-first'."
+ "Remove the first item from LIST for which FORM evals to non-nil.
+Each element of LIST in turn is bound to `it' and its index
+within LIST to `it-index' before evaluating FORM. This is a
+non-destructive operation, but only the front of LIST leading up
+to the removed item is a copy; the rest is LIST's original tail.
+If no item is removed, then the result is a complete copy.
+This is the anaphoric counterpart to `-remove-first'."
(declare (debug (form form)))
- `(-remove-first (lambda (it) ,form) ,list))
+ (let ((front (make-symbol "front"))
+ (tail (make-symbol "tail")))
+ `(let ((,tail ,list) ,front)
+ (--each-while ,tail (not ,form)
+ (push (pop ,tail) ,front))
+ (if ,tail
+ (nconc (nreverse ,front) (cdr ,tail))
+ (nreverse ,front)))))
+
+(defun -remove-first (pred list)
+ "Remove the first item from LIST for which PRED returns non-nil.
+This is a non-destructive operation, but only the front of LIST
+leading up to the removed item is a copy; the rest is LIST's
+original tail. If no item is removed, then the result is a
+complete copy.
+Alias: `-reject-first'.
+This function's anaphoric counterpart is `--remove-first'.
+See also `-map-first', `-remove-item', and `-remove-last'."
+ (--remove-first (funcall pred it) list))
(defalias '-reject-first '-remove-first)
(defalias '--reject-first '--remove-first)
diff --git a/dash.texi b/dash.texi
index ae9b03d..a98d7df 100644
--- a/dash.texi
+++ b/dash.texi
@@ -528,24 +528,27 @@ For similar operations, see also @code{-keep}
(@pxref{-keep}) and @code{-filter}
@anchor{-remove-first}
@defun -remove-first (pred list)
-Return a new list with the first item matching @var{pred} removed.
-
-Alias: @code{-reject-first}
-
-See also: @code{-remove} (@pxref{-remove}), @code{-map-first}
(@pxref{-map-first})
+Remove the first item from @var{list} for which @var{pred} returns non-nil.
+This is a non-destructive operation, but only the front of @var{list}
+leading up to the removed item is a copy; the rest is @var{list}'s
+original tail. If no item is removed, then the result is a
+complete copy.
+Alias: @code{-reject-first}.
+This function's anaphoric counterpart is @code{--remove-first}.
+See also @code{-map-first} (@pxref{-map-first}), @code{-remove-item}
(@pxref{-remove-item}), and @code{-remove-last} (@pxref{-remove-last}).
@example
@group
-(-remove-first 'even? '(1 3 5 4 7 8 10))
- @result{} '(1 3 5 7 8 10)
+(-remove-first #'natnump '(-2 -1 0 1 2))
+ @result{} '(-2 -1 1 2)
@end group
@group
-(-remove-first 'stringp '(1 2 "first" "second" "third"))
- @result{} '(1 2 "second" "third")
+(-remove-first #'stringp '(1 2 "first" "second"))
+ @result{} '(1 2 "second")
@end group
@group
-(--remove-first (> it 3) '(1 2 3 4 5 6 7 8 9 10))
- @result{} '(1 2 3 5 6 7 8 9 10)
+(--remove-first (> it 3) '(1 2 3 4 5 6))
+ @result{} '(1 2 3 5 6)
@end group
@end example
@end defun
diff --git a/dev/examples.el b/dev/examples.el
index c2e6dbf..30e55c3 100644
--- a/dev/examples.el
+++ b/dev/examples.el
@@ -160,13 +160,16 @@ new list."
(--remove nil '(1)) => '(1))
(defexamples -remove-first
- (-remove-first 'even? '(1 3 5 4 7 8 10)) => '(1 3 5 7 8 10)
- (-remove-first 'stringp '(1 2 "first" "second" "third")) => '(1 2 "second"
"third")
- (--remove-first (> it 3) '(1 2 3 4 5 6 7 8 9 10)) => '(1 2 3 5 6 7 8 9 10)
- (-remove-first 'even? '(2 3 4)) => '(3 4)
- (-remove-first 'even? '(3 5 7 4)) => '(3 5 7)
- (-remove-first 'even? '(2)) => nil
- (-remove-first 'even? '(1 3 5 7)) => '(1 3 5 7))
+ (-remove-first #'natnump '(-2 -1 0 1 2)) => '(-2 -1 1 2)
+ (-remove-first #'stringp '(1 2 "first" "second")) => '(1 2 "second")
+ (--remove-first (> it 3) '(1 2 3 4 5 6)) => '(1 2 3 5 6)
+ (-remove-first #'natnump '(2 3 4)) => '(3 4)
+ (-remove-first #'natnump '(-3 -2 -1 4)) => '(-3 -2 -1)
+ (-remove-first #'natnump '(2)) => '()
+ (-remove-first #'natnump '()) => '()
+ (-remove-first #'null '(1 3 5 7)) => '(1 3 5 7)
+ (let ((l (list 1 2))) (setcar (-remove-first #'identity l) 0) l) => '(1 0)
+ (let ((l (list 1 2))) (setcar (-remove-first #'null l) 0) l) => '(1 2))
(defexamples -remove-last
(-remove-last 'even? '(1 3 5 4 7 8 10 11)) => '(1 3 5 4 7 8 11)
- [elpa] externals/dash 3694ae9 236/316: * dash.el (-iota): Simplify and purify., (continued)
- [elpa] externals/dash 3694ae9 236/316: * dash.el (-iota): Simplify and purify., ELPA Syncer, 2021/02/15
- [elpa] externals/dash ca36c57 239/316: Allow -lambda with no arguments, ELPA Syncer, 2021/02/15
- [elpa] externals/dash bf8a462 243/316: Partially revert last change, ELPA Syncer, 2021/02/15
- [elpa] externals/dash d7d0acb 242/316: Don't call eval, ELPA Syncer, 2021/02/15
- [elpa] externals/dash bf8d876 238/316: Merge pull request #363 from blc/list, ELPA Syncer, 2021/02/15
- [elpa] externals/dash 76ace7f 240/316: Fix error signaling, ELPA Syncer, 2021/02/15
- [elpa] externals/dash 1ccf08d 244/316: ; Fix last change, ELPA Syncer, 2021/02/15
- [elpa] externals/dash 2625bc5 247/316: Don't use insert-file-contents-literally, ELPA Syncer, 2021/02/15
- [elpa] externals/dash 7583e65 248/316: Revert --map to using mapcar, ELPA Syncer, 2021/02/15
- [elpa] externals/dash 6f5888c 251/316: Extend --filter and --remove docs and tests, ELPA Syncer, 2021/02/15
- [elpa] externals/dash db45ee7 252/316: Optimize -remove-first a bit,
ELPA Syncer <=
- [elpa] externals/dash 0e5acda 260/316: Simplify -non-nil, ELPA Syncer, 2021/02/15
- [elpa] externals/dash 9ad0d2b 266/316: Extend -map-indexed docs and tests, ELPA Syncer, 2021/02/15
- [elpa] externals/dash f61769d 256/316: * dash.el (dash--keywords): Prefer rx., ELPA Syncer, 2021/02/15
- [elpa] externals/dash 2aeb4e4 264/316: Use actual advertised function signature in README, ELPA Syncer, 2021/02/15
- [elpa] externals/dash a536770 267/316: Prefer relative image links in README, ELPA Syncer, 2021/02/15
- [elpa] externals/dash ce4a344 258/316: Eliminate odd? from examples, ELPA Syncer, 2021/02/15
- [elpa] externals/dash f3ae7bb 259/316: Alias -remove-item to remove, ELPA Syncer, 2021/02/15
- [elpa] externals/dash 525ede2 265/316: Improve docstring Markdown formatting, ELPA Syncer, 2021/02/15
- [elpa] externals/dash 4a32a5d 257/316: Write -remove-last in terms of --remove-last, ELPA Syncer, 2021/02/15
- [elpa] externals/dash cbd3b29 268/316: * .elpaignore: Exclude dev/ from GNU ELPA tarball., ELPA Syncer, 2021/02/15