sort with :key in Lisp
Sorts an alist of cheese wheels by weight and by name, copying first because sort is destructive.
;; SORT is destructive: it rearranges the sequence you hand it, so
;; pass a COPY-LIST whenever the original still matters.
(defvar *wheels*
'(("gouda" . 4200) ("brie" . 900) ("comte" . 12500)))
;; :KEY pulls the part to compare out of each element, and the
;; predicate then sees only that part.
(defvar *by-weight* (sort (copy-list *wheels*) #'< :key #'cdr))
(defvar *by-name* (sort (copy-list *wheels*) #'string< :key #'car))
(defvar *heaviest* (car (last *by-weight*)))
(format t "by weight ~a~%" (mapcar #'car *by-weight*))
(format t "by name ~a~%" (mapcar #'car *by-name*))
(format t "heaviest ~a at ~a g~%" (car *heaviest*) (cdr *heaviest*))
How it works
(sort (copy-list *wheels*) #'< :key #'cdr)orders by weight and protects*wheels*from being rearranged.(sort (copy-list *wheels*) #'string< :key #'car)swaps in a string predicate and reads the other half of each cons.(car (last *by-weight*))takes the heaviest wheel off the sorted end.
Keywords and builtins used here
carcdrdefvarformatlastmapcarsort
The run, in numbers
- Lines
- 14
- Characters to type
- 653
- Tokens
- 104
- Three-star pace
- 70 tpm
At the three-star pace of 70 tokens a minute, this run takes about 89 seconds.
Step 3 of 3 in Higher-order, step 15 of 27 in Language basics.