In doing a problem set from the Internet a few weeks ago, I found myself writing awkward constructions with
LOOP to try to find the best one (or two or three) things in a big bag of things based on various criteria: similarity to English, hamming distance from their neighbor, etc.
I wrote a macro that encapsulated the pattern. I’ve reworked that macro into a library for public use.
- Home page: http://nklein.com/software/track-best-library/
- Main git repository: http://git.nklein.com/lisp/libs/track-best.git
- Browsable repository: https://github.com/nklein/track-best
Here is one example to pique your interest. Suppose you have some data about the elevations of various cities in various states and you (being a Moxy Fruvous fan) want to know
What Is the Lowest Highest Point? Here’s how you might tackle that with the
(let ((data '(("Alabama" ("Birmingham" 664) ("Mobile" 218) ("Montegomery" 221)) ("Alaska" ("Anchorage" 144) ("Fairbanks" 531)) ("Arizona" ("Grand Canyon" 6606) ("Phoenix" 1132) ("Tuscon" 2641))))) (with-track-best (:order-by-fn #'<) (dolist (state-info data) (multiple-value-bind (city altitude) (with-track-best () (dolist (city-info (rest state-info)) (track (first city-info) (second city-info)))) (track (list (first state-info) city) altitude)))))
With this limited dataset, the end result would be
(VALUES '("Alaska" "Fairbanks") 531). The inner
WITH-TRACK-BEST finds the highest city in each state. The outer
WITH-TRACK-BEST finds the lowest of these.