typestar

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

  1. (remove-if #'evenp *sightings*) drops the matches and (remove-if-not #'evenp *sightings*) keeps them.
  2. (remove-if (lambda (n) (< n 10)) *sightings*) shows a lambda in the predicate slot.
  3. (count-if (lambda (n) (>= n 10)) *sightings*) returns a tally rather than a new list.

Keywords and builtins used here

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.

Type this snippet

Step 2 of 3 in Higher-order, step 14 of 27 in Language basics.

← Previous Next →