From ac02066a55d3a19c41a70ad5b71d02c49a28e282 Mon Sep 17 00:00:00 2001 From: Ken Harris Date: Wed, 12 Jun 2013 23:07:23 -0700 Subject: [PATCH] POSITION-IF, POSITION-IF-NOT (except :FROM-END) --- src/sequence.lisp | 16 ++++++++++++++++ tests/seq.lisp | 4 ++++ 2 files changed, 20 insertions(+) diff --git a/src/sequence.lisp b/src/sequence.lisp index 981f559..7f86a85 100644 --- a/src/sequence.lisp +++ b/src/sequence.lisp @@ -63,6 +63,22 @@ :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) diff --git a/tests/seq.lisp b/tests/seq.lisp index c39b0ce..ce1c8d6 100644 --- a/tests/seq.lisp +++ b/tests/seq.lisp @@ -37,6 +37,10 @@ (test (= (position 1 #(1 1 3) :test-not #'=) 2)) (test (= (position 1 '(1 1 3) :test-not #'=) 2)) +;; POSITION-IF, POSITION-IF-NOT +(test (= 2 (position-if #'oddp '((1) (2) (3) (4)) :start 1 :key #'car))) +(test (= 4 (position-if-not #'integerp '(1 2 3 4 X)))) ;; (hyperspec example used "5.0", but we don't have a full numeric tower yet!) + ; REMOVE-IF (test (equal (remove-if #'zerop '(1 0 2 0 3)) '(1 2 3))) (test (equal (remove-if-not #'zerop '(1 0 2 0 3)) '(0 0))) -- 1.7.10.4