mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2025-01-07 15:21:46 +00:00
Speed up butlast
* lisp/subr.el (butlast): Don't duplicate the removed part. * test/lisp/subr-tests.el (subr-tests--butlast-ref, subr-butlast): Add test.
This commit is contained in:
parent
4b807380cf
commit
c80adde1d9
11
lisp/subr.el
11
lisp/subr.el
@ -707,11 +707,14 @@ If N is bigger than the length of LIST, return LIST."
|
||||
|
||||
(defun butlast (list &optional n)
|
||||
"Return a copy of LIST with the last N elements removed.
|
||||
If N is omitted or nil, the last element is removed from the
|
||||
copy."
|
||||
If N is omitted or nil, return a copy of LIST without its last element.
|
||||
If N is zero or negative, return LIST."
|
||||
(declare (side-effect-free t))
|
||||
(if (and n (<= n 0)) list
|
||||
(nbutlast (copy-sequence list) n)))
|
||||
(unless n
|
||||
(setq n 1))
|
||||
(if (<= n 0)
|
||||
list
|
||||
(take (- (length list) n) list)))
|
||||
|
||||
(defun nbutlast (list &optional n)
|
||||
"Modify LIST to remove the last N elements.
|
||||
|
@ -1090,5 +1090,22 @@ final or penultimate step during initialization."))
|
||||
(should-not (plistp '(1 2 3)))
|
||||
(should-not (plistp '(1 2 3 . 4))))
|
||||
|
||||
(defun subr-tests--butlast-ref (list &optional n)
|
||||
"Reference implementation of `butlast'."
|
||||
(let ((m (or n 1))
|
||||
(len (length list)))
|
||||
(let ((r nil))
|
||||
(while (and list (> len m))
|
||||
(push (car list) r)
|
||||
(setq list (cdr list))
|
||||
(setq len (1- len)))
|
||||
(nreverse r))))
|
||||
|
||||
(ert-deftest subr-butlast ()
|
||||
(dolist (l '(nil '(a) '(a b) '(a b c) '(a b c d)))
|
||||
(dolist (n (cons nil (number-sequence -2 6)))
|
||||
(should (equal (butlast l n)
|
||||
(subr-tests--butlast-ref l n))))))
|
||||
|
||||
(provide 'subr-tests)
|
||||
;;; subr-tests.el ends here
|
||||
|
Loading…
Reference in New Issue
Block a user