emacs-elpa-diffs
[Top][All Lists]
Advanced

[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)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]