I have the list in LISP:
((1 b) (1 a) (2 D) (1 z) (1 t) (2 a) (3 n))
I have to order it first on the number and if equal on the lexichographic order of the char, the output should be:
((1 a) (1 b) (1 t) (1 z) (2 a) (2 d) (3 n))
I have tried to sort on one parameter and then the other, how can I compose the two function ?
;;(sort '((1 b) (1 a) (2 D) (1 z) (1 t) (2 a) (3 n)) #'< :key #'car )
;;(sort '((1 b) (1 a) (2 D) (1 z) (1 t) (2 a) (3 n)) #'string< :key #'second )
Are there easier ways to do it?
Thanks
As coredump says, since you really need a list comparison function, a nice approach is do the meta thing: don't write one, but write a function which makes functions which compare lists. Here is such a function:
(defun make-list-comparator (&rest predicates)
(labels ((tails< (l1t l2t pt)
(let ((< (first pt))
(e1 (first l1t))
(e2 (first l2t)))
(cond
((funcall < e1 e2) t)
((funcall < e2 e1) nil)
((and (null l1t) (null l2t) (null pt)) nil)
((or (null l1t) (null l2t) (null pt))
(error "crashed into the end"))
(t (tails< (rest l1t) (rest l2t) (rest pt)))))))
(lambda (l1 l2)
(tails< l1 l2 predicates))))
And now
> (sort (copy-list '((1 b) (1 a) (2 D) (1 z) (1 t) (2 a) (1)))
(make-list-comparator
#'<
(lambda (s1 s2)
(string< (string s1) (string s2)))))
((1 a) (1 b) (1 t) (1 z) (2 a) (2 d) (3 n))