Filtering with predicates in Lisp
Filters a list of bird counts three ways and tallies a fourth, without changing the original list.
;; REMOVE-IF drops the elements a predicate accepts; REMOVE-IF-NOT
;; keeps them. Both return a fresh list and leave the input alone.
(defvar *sightings* '(3 12 7 20 5 8 15))
(defvar *odd-counts* (remove-if #'evenp *sightings*))
(defvar *even-counts* (remove-if-not #'evenp *sightings*))
;; A lambda serves anywhere a named predicate does.
(defvar *flocks* (remove-if (lambda (n) (< n 10)) *sightings*))
;; COUNT-IF answers how many match without building a new list.
(defvar *big-days* (count-if (lambda (n) (>= n 10)) *sightings*))
(format t "odd ~a~%even ~a~%" *odd-counts* *even-counts*)
(format t "flocks ~a on ~a days~%" *flocks* *big-days*)
How it works
(remove-if #'evenp *sightings*)drops the matches and(remove-if-not #'evenp *sightings*)keeps them.(remove-if (lambda (n) (< n 10)) *sightings*)shows a lambda in the predicate slot.(count-if (lambda (n) (>= n 10)) *sightings*)returns a tally rather than a new list.
Keywords and builtins used here
defvarevenpformatlambda
The run, in numbers
- Lines
- 15
- Characters to type
- 651
- Tokens
- 90
- Three-star pace
- 70 tpm
At the three-star pace of 70 tokens a minute, this run takes about 77 seconds.
Step 2 of 3 in Higher-order, step 14 of 27 in Language basics.