(return-from every nil)))
t)
-
-;;; TODO: Support both List and vectors in the following functions
-
-(defun remove-if (func list)
+(defun remove-if (func seq)
(cond
- ((null list)
- nil)
- ((funcall func (car list))
- (remove-if func (cdr list)))
- (t
- ;;
- (cons (car list) (remove-if func (cdr list))))))
+ ((listp seq) (list-remove-if func seq nil))
+ ((arrayp seq) (vector-remove-if func seq nil))
+ (t (error "`~S' is not of type SEQUENCE" seq))))
-(defun remove-if-not (func list)
+(defun remove-if-not (func seq)
(cond
- ((null list)
- nil)
- ((funcall func (car list))
- (cons (car list) (remove-if-not func (cdr list))))
- (t
- (remove-if-not func (cdr list)))))
+ ((listp seq) (list-remove-if func seq t))
+ ((arrayp seq) (vector-remove-if func seq t))
+ (t (error "`~S' is not of type SEQUENCE" seq))))
+
+(defun list-remove-if (func list negate)
+ (if (endp list)
+ ()
+ (let ((test (funcall func (car list))))
+ (if (if negate (not test) test)
+ (list-remove-if func (cdr list) negate)
+ (cons (car list) (list-remove-if func (cdr list) negate))))))
+
+(defun vector-remove-if (func vector negate)
+ (let ((out-vector (make-array 0)))
+ (dotimes (i (length vector))
+ (let* ((element (aref vector i))
+ (test (funcall func element)))
+ (when (if negate test (not test))
+ (vector-push-extend element out-vector))))
+ out-vector))
+
+;;; TODO: Support both List and vectors in the following functions
(defun subseq (seq a &optional b)
(if b
(slice seq a b)
(slice seq a)))
-
(test (find 1 (list 2 1 3)))
(test (not (find 1 (list 2 2 2))))
(test (not (find 1 (remove 1 (list 1 2 3 1)))))
+
+(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)))
+
+;; TODO: Rewrite these tests when EQUALP exists and works on vectors
+(let ((v1 (remove-if #'zerop #(1 0 2 0 3))))
+ (test (and (= (aref v1 0) 1) (= (aref v1 1) 2) (= (aref v1 2) 3))))
+(test (every #'zerop (remove-if-not #'zerop #(1 0 2 0 3))))