j2lstaples Posted August 1, 2023 Posted August 1, 2023 This is just caution for those of you who would like to sort your lists of any kind. If you're dealing with integers in your compare function, vl-sort will ruin your list. I have a very simple test case for this. Suppose: (setq lst '(0 0 0 1 0 0 0)) And you want to sort this list such that: sort-list = (0 0 0 0 0 0 1) You think you would use a simple implementation of vl-sort like the following: (setq sort-list (vl-sort lst '(lambda (s1 s2) (<= s1 s2)))) It seems alright and you even considered that two values might be the same. So, fine and dandy, right? WRONG What this will show is that: sort-list = (0 1) Now you lost information. Now, you might be working with a list of entity names and you use the compare function. '(lambda (s1 s2) (<= (atoi (LM:vl-getattributevalue (vlax-ename->vla-object s1) "ITEM_NO") (atoi (LM:vl-getattributevalue (vlax-ename->vla-object s2) "ITEM_NO"))) How will you be able to know that it didn't just skip or remove a block from your sorted list. Should you even trust this function? *end of rant* Quote
j2lstaples Posted August 1, 2023 Author Posted August 1, 2023 You'd have to use something like what Kent1Cooper on the AutoCAD forums posted: (mapcar 'cdr (vl-sort (mapcar '(lambda (x) (cons 1 x)) lst) '(lambda (y z) (< (cdr y) (cdr z))))) Quote
BIGAL Posted August 2, 2023 Posted August 2, 2023 Using Vl-sort need to take into account type of items in list strings, real and integers, or combinations. So theVL-sort is slightly different. You can sort a list to multiple depths I have some code taht looks at up to the first 5 items in a list used with extract quantities. ;x only (setq lst (vl-sort lst '(lambda (x y) (< (car x)(car y))))) (vl-sort '(3 2 1 20 98.32 16 0 20 -2.345) '<) (-2.345 0 1 2 3 16 20 98.32) only 1 20 (setq test '(87 6.54 20 1 8.88 20)) ; contains two 20's (mapcar 'cdr (vl-sort (mapcar '(lambda (x) (cons 1 x)) test) '(lambda (y z) (< (cdr y) (cdr z))))) returns: (1 6.54 8.88 20 20 87); both 20's still there ; sorts on 1st two items (vl-sort lst '(lambda (a b) (cond ((< (car a) (car b))) ((= (car a) (car b)) (< (cadr a) (cadr b))) ) ) ) 1 Quote
abra-CAD-abra Posted August 2, 2023 Posted August 2, 2023 (mapcar '(lambda ( x ) (nth x lst)) (vl-sort-i lst '<)) 1 Quote
marko_ribar Posted August 2, 2023 Posted August 2, 2023 (edited) Iterative version : (defun _vl-sort ( l f / *q* ll ff gg ) (if (= (type f) 'sym) (setq f (eval f)) ) (while (setq *q* (car l)) (setq ll (if (null ll) (cons *q* ll) (cond ( (apply f (list (last ll) *q*)) (append ll (list *q*)) ) ( (apply f (list *q* (car ll))) (cons *q* ll) ) ( t (setq ff nil) (setq gg (apply (function append) (append (mapcar (function (lambda ( *xxx* *yyy* ) (if (null ff) (if (apply f (list *q* *yyy*)) (progn (setq ff t) (list *xxx* *q*)) (list *xxx*) ) (list *xxx*) ) )) ll (cdr ll) ) (list (list (last ll))) )) ) (if (null ff) (append ll (list *q*)) gg ) ) ) ) ) (setq l (cdr l)) ) ll ) HTH., M.R. Edited August 2, 2023 by marko_ribar Quote
marko_ribar Posted August 2, 2023 Posted August 2, 2023 Recursive version : http://elpanov.com/index.php?id=67 Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.