View Single Post
Old 03-21-2006, 02:56 AM   #5 (permalink)
teknomage1
Jack of all trades
 
teknomage1's Avatar
 
Join Date: Feb 2005
Location: Los Angeles
Posts: 598
teknomage1 is on a distinguished road
Send a message via AIM to teknomage1
LOOP is a bitch, plain and simple. It's easier to look at this as a MAP problem i believe. MAP is like foreach for list elements and vectors. So assuming you have an a-list like I descibed above that relates models to manufacturers, you could then use MAP to run over a list of manufacturers and use REMOVE-IF-NOT to select only the models of that manufacturer.
REMOVE-IF-NOT takes a predicate function as it's first parameter so that's where we want to test and see if the result of the :key expression is equal to the manufacturer we're looking at. Since there is no built in function to do this and it is too specific to define a new function for, we can use the LAMBDA function to generate a new anonymous function. The :key function is evaluated for each element REMOVE-IF-NOT examines before it goes to the predicate function. In this case we want the manufacturor of the model so we look it up from the a-list.
Code:
(defparameter *models* '(fiesta ford sk100 merc focus ford 1series bmw))

(defun order-models (model-list manufacturer-list)
  (map 'list
       (lambda (m)
	 (list m (remove-if-not
		  (lambda (y) (equal y m))
		  model-list
		  :key (lambda (x) (getf *models* x)))))
       manufacturer-list))
(order-models '(fiesta sk100 focus 1series) '(bmw ford merc))
=>
((BMW (1SERIES)) (FORD (FIESTA FOCUS)) (MERC (SK100)))
__________________
Stop intellectual property from infringing on me
teknomage1 is offline   Reply With Quote