X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fsequence.lisp;h=cda0b411dfb489547718835272fc9d2ea54cb898;hb=546ad39c2c44148207a1fde5b45957f2945ad1cf;hp=d7dae46b1b98c9656e9b675d03f8055b7b059879;hpb=c493bb2c2fed02d7cfb08599e6146de43e9a40d6;p=jscl.git diff --git a/src/sequence.lisp b/src/sequence.lisp index d7dae46..cda0b41 100644 --- a/src/sequence.lisp +++ b/src/sequence.lisp @@ -48,14 +48,38 @@ (when (funcall predicate x) (return x))))) -(defun position (elt sequence &key key (test #'eql testp) - (test-not #'eql test-not-p)) - (do-sequence (x sequence index) - (when (satisfies-test-p elt x :key key :test test :testp testp - :test-not test-not :test-not-p test-not-p ) - (return index)))) - -(defun remove (x seq) +(defun position (elt sequence + &key key (test #'eql testp) + (test-not #'eql test-not-p) + (start 0) end) + ;; TODO: Implement START and END efficiently for all the sequence + ;; functions. + (let ((end (or end (length sequence)))) + (do-sequence (x sequence index) + (when (and (<= start index) + (< index end) + (satisfies-test-p elt x + :key key :test test :testp testp + :test-not test-not :test-not-p test-not-p)) + (return index))))) + +;; TODO: need to support &key from-end +(defun position-if (predicate sequence + &key key (start 0) end) + ;; TODO: Implement START and END efficiently for all the sequence + ;; functions. + (let ((end (or end (length sequence)))) + (do-sequence (x sequence index) + (when (and (<= start index) + (< index end) + (funcall predicate (if key (funcall key x) x))) + (return index))))) + +(defun position-if-not (predicate sequence + &key key (start 0) end) + (position-if (complement predicate) sequence :key key :start start :end end)) + +(defun remove (x seq &key key (test #'eql testp) (test-not #'eql test-not-p)) (cond ((null seq) nil) @@ -63,7 +87,8 @@ (let* ((head (cons nil nil)) (tail head)) (do-sequence (elt seq) - (unless (eql x elt) + (unless (satisfies-test-p x elt :key key :test test :testp testp + :test-not test-not :test-not-p test-not-p) (let ((new (list elt))) (rplacd tail new) (setq tail new)))) @@ -71,7 +96,8 @@ (t (let (vector) (do-sequence (elt seq index) - (if (eql x elt) + (if (satisfies-test-p x elt :key key :test test :testp testp + :test-not test-not :test-not-p test-not-p) ;; Copy the beginning of the vector only when we find an element ;; that does not match. (unless vector @@ -128,7 +154,7 @@ (if b (let ((diff (- b a))) (cond - ((zerop diff) ()) + ((zerop diff) ()) ((minusp diff) (error "Start index must be smaller than end index")) (t @@ -138,11 +164,18 @@ (setq pointer (cdr pointer)) (when (null pointer) (error "Ending index larger than length of list"))) - (rplacd pointer ()) + (rplacd pointer ()) drop-a)))) (copy-list (nthcdr a seq)))) - ((arrayp seq) - (if b - (slice seq a b) - (slice seq a))) + ((vectorp seq) + (let* ((b (or b (length seq))) + (size (- b a)) + (new (make-array size :element-type (array-element-type seq)))) + (do ((i 0 (1+ i)) + (j a (1+ j))) + ((= j b) new) + (aset new i (aref seq j))))) (t (not-seq-error seq)))) + +(defun copy-seq (sequence) + (subseq sequence 0))