I have a list of lists. (("cal" "623") ("bill" "156") ("joe" "389"))
What is the most efficent way to sort a list like this in lisp, sorting
by either the numbers or the names?
Thanks
Scott
In article <·············@lmtas.lmco.com>, Mark Fransen
<·········@lmtas.lmco.com> wrote:
> I have a list of lists. (("cal" "623") ("bill" "156") ("joe" "389"))
> What is the most efficent way to sort a list like this in lisp, sorting
> by either the numbers or the names?
>
Well you really don't have numbers. You have strings, even "156" is a
string, not a number. And sorting a string that is a number, as a number,
would be slower than sorting the "names". If, however, you could *easily*
have numbers rather than strings of numbers, you could sort faster still.
That is:
(("cal" 623) ("bill" 156) ("joe" 389)) sort fastest using numbers
(sort list #'(lambda (item1 item2) (< (first item1) (first item2))))
(("cal" "623") ("bill" "156") ("joe" "389")) sort next fastest using names
(sort list #'(lambda (item1 item2) (string-lessp (first item1) (first item2))))
(("cal" "623") ("bill" "156") ("joe" "389")) sort slowest using "numbers"
(sort list #'(lambda (item1 item2) (< (read-from-string (first item1))
(read-from-string (first item2))))
or slightly more efficiently if a long list is sorted
(let ((list2 (loop for item in list collect (list (first item)
(read-from-string
(second item))))))
(sort list #'(lambda (item1 item2) (< (first item1) (first item2)))))
or, if you can destructively modify your list you can do
(progn
(loop for item in list do (setf (second item) (read-from-string (second item))))
(sort list #'(lambda (item1 item2) (< (first item1) (first item2)))))
--
···········@novia.net
Omaha, NE
http://www.novia.net/~vogt/
····@novia.net (Christopher J. Vogt) writes:
> (("cal" 623) ("bill" 156) ("joe" 389)) sort fastest using numbers
> (sort list #'(lambda (item1 item2) (< (first item1) (first item2))))
I think you want to use the `:key' argument to SORT, and simply #'< as
the predicate.
It should provide a faster sort.
--
Hrvoje Niksic <·······@srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
"Silence!" cries Freydag. "I did not call thee in for a consultation!"
"They are my innards! I will not have them misread by a poseur!"
Mark Fransen <·········@lmtas.lmco.com> writes:
> I have a list of lists. (("cal" "623") ("bill" "156") ("joe" "389"))
> What is the most efficent way to sort a list like this in lisp, sorting
> by either the numbers or the names?
I hope you notice that the numbers are actually strings. If you want
to sort by strings (CAR), use this:
(let ((list '(("cal" 623) ("bill" 156) ("joe" 389))))
(sort list 'string< :key #'car))
=> (("bill" 156) ("cal" 623) ("joe" 389))
(let ((list '(("cal" 623) ("bill" 156) ("joe" 389))))
(sort list '< :key #'cadr))
=> (("bill" 156) ("joe" 389) ("cal" 623))
(tested with ACL)
Note that SORT is a destructive, which is to say that it reuses the
existing storage, and you shouldn't use the original list. So, if you
define a function:
(defun sort-car (list)
(sort list 'string< :key #'car))
After calling:
(setq sorted-list (sort-car my-precious-list)).
you should *no longer use* the contents of MY-PRECIOUS-LIST. If you
want use the old list, copy it first:
(defun safe-sort-car (list)
(sort (copy-list list) 'string< :key #'car))
--
Hrvoje Niksic <·······@srce.hr> | Student at FER Zagreb, Croatia
--------------------------------+--------------------------------
main(){printf(&unix["\021%six\012\0"],(unix)["have"]+"fun"-0x60);}
In article <·············@lmtas.lmco.com>, Mark Fransen
<·········@lmtas.lmco.com> wrote:
> I have a list of lists. (("cal" "623") ("bill" "156") ("joe" "389"))
> What is the most efficent way to sort a list like this in lisp, sorting
> by either the numbers or the names?
How about:
; By number
(let ((list '(("cal" "623") ("bill" "156") ("joe" "389"))))
(sort list #'< :key #'(lambda (item)
(parse-integer (second item)))))
; By string
(let ((list '(("cal" "623") ("bill" "156") ("joe" "389"))))
(sort list #'string< :key #'first))
--
http://www.lavielle.com/~joswig/