vl-sort a list of lists

vl-sort a list of lists

dvertz
Collaborator Collaborator
505 Views
6 Replies
Message 1 of 7

vl-sort a list of lists

dvertz
Collaborator
Collaborator

I have a list of lists I would like to sort by two entries. I once had a need to do a sort and the forum helped a lot. So, I thought I would ask again. I thought I would first attempt the code I was once given and as I was studying how it worked and how I could use it, I found that vl-sort will remove duplicate items. And then someone posted code in CADTutor that Kent1Cooper had wrote using mapcar to retain the duplicates. His code is slightly above my abilities.

 

My list is:

(setq LST
'(((1 . "T1") (2 . "l-cre-non.dwg") (3 . 4) (4 . "CREPE MYRTLE") (5 . 8) (6 . 1))
((1 . "T2") (2 . "l-mag-non.dwg") (3 . 12) (4 . "MAGNOLIA") (5 . 24) (6 . 1))
((1 . "T3") (2 . "l-oak-non.dwg") (3 . 10) (4 . "OAK") (5 . 20) (6 . 1))
((1 . "T4") (2 . "l-app-non.dwg") (3 . 12) (4 . "APPLE") (5 . 24) (6 . 1))
((1 . "T5") (2 . "l-app-non.dwg") (3 . 8) (4 . "APPLE") (5 . 16) (6 . 2))
))

 

I would like to first sort by association 4 (cdr (assoc 4 LST)), then by association 3 (cdr (assoc 3 LST))

The list should be returned as:

 

(setq LST
'(((1 . "T5") (2 . "l-app-non.dwg") (3 . 8) (4 . "APPLE") (5 . 16) (6 . 2))
((1 . "T4") (2 . "l-app-non.dwg") (3 . 12) (4 . "APPLE") (5 . 24) (6 . 1))
((1 . "T1") (2 . "l-cre-non.dwg") (3 . 4) (4 . "CREPE MYRTLE") (5 . 8) (6 . 1))
((1 . "T2") (2 . "l-mag-non.dwg") (3 . 12) (4 . "MAGNOLIA") (5 . 24) (6 . 1))
((1 . "T3") (2 . "l-oak-non.dwg") (3 . 10) (4 . "OAK") (5 . 20) (6 . 1))
))

 

I would appreciate any help given. Thanks.

Civil 3D 2022,
Windows 10 Pro, x64, Nvidia Quadro P1000
Intel Core i9-11900k; 3.50GHz, 32 GB RAM, 500GB WD BLACK M.2


0 Likes
Accepted solutions (1)
506 Views
6 Replies
Replies (6)
Message 2 of 7

ВeekeeCZ
Consultant
Consultant
Accepted solution

Try these. It shouldn't remove any items.

(setq lst (vl-sort lst '(lambda (e1 e2) (< (cdr (nth 2 e1)) (cdr (nth 2 e2))))))

(setq lst (vl-sort lst '(lambda (e1 e2) (< (cdr (nth 3 e1)) (cdr (nth 3 e2))))))

 

or you can use your assoc as well

(setq lst (vl-sort lst '(lambda (e1 e2) (< (cdr (assoc 3 e1)) (cdr (assoc 3 e2))))))

(setq lst (vl-sort lst '(lambda (e1 e2) (< (cdr (assoc 4 e1)) (cdr (assoc 4 e2))))))

0 Likes
Message 3 of 7

Kent1Cooper
Consultant
Consultant

I would take a look, but so I don't have to start from scratch, post a link to the Cadtutor place with the code, or the code itself if it's not too long.  [I don't participate there, but I'm happy to see things spread around.  Whoever posted it must have gotten it from here somewhere -- a link to that somewhere would also suffice, if that's how they posted it.]

Kent Cooper, AIA
0 Likes
Message 4 of 7

dvertz
Collaborator
Collaborator

BeekeeCZ,

Thank you so much, I did not think it would be that simple. That is code I can actually understand (mostly). I thought that code would remove the duplicate "Apple".

 

Kent1Cooper,

Thanks for the reply. BeekeeCZ appears to have the solution. I have only ran one test, so I'll need to run more to be sure. But currently it seems where I had worked out a bug in my code, another has presented itself in building the list of lists. More debugging to do. But if you would like to look at where you were mention (yes. they said it was from the Autodesk forums), here is the link: https://www.cadtutor.net/forum/topic/78029-vl-sort-kinda-sucks/

Civil 3D 2022,
Windows 10 Pro, x64, Nvidia Quadro P1000
Intel Core i9-11900k; 3.50GHz, 32 GB RAM, 500GB WD BLACK M.2


0 Likes
Message 5 of 7

MunteanStefan
Contributor
Contributor

vl-sort removes duplicates only in lists of integers. 

For your sample, you can use this:

 

(vl-sort lst
 '(lambda (a b)
    (if
      (eq (cdr (assoc 4 a)) (cdr (assoc 4 b)))
      (< (cdr (assoc 3 a)) (cdr (assoc 3 b)))
      (< (cdr (assoc 4 a)) (cdr (assoc 4 b)))
    )
  )
)

 

0 Likes
Message 6 of 7

dvertz
Collaborator
Collaborator

MunteanStefan,

 

Thanks for that info. I will keep that in mind next time I attempt using vl-sort.

Civil 3D 2022,
Windows 10 Pro, x64, Nvidia Quadro P1000
Intel Core i9-11900k; 3.50GHz, 32 GB RAM, 500GB WD BLACK M.2


0 Likes
Message 7 of 7

Sea-Haven
Mentor
Mentor

Just a comment do you really need the list to be a dotted pair ? Why not just a plain list, each item can still be found using nth x lst) and sort on (nth 3 lst)

(1 . "T5") (2 . "l-app-non.dwg") (3 . 8) (4 . "APPLE") (5 . 16) (6 . 2))


("T5" "l-app-non.dwg" 8 "APPLE" 16 2)

 

(setq LST
'(
("T1" "l-cre-non.dwg" 4 "CREPE MYRTLE" 8 1)
("T2" "l-mag-non.dwg" 12 "MAGNOLIA" 24 1)
("T3" "l-oak-non.dwg" 10 "OAK" 20 1)
("T4" "l-app-non.dwg" 12 "APPLE" 24 1)
("T5" "l-app-non.dwg" 8  "APPLE" 16 2)
)
)

; sorts on two items
(setq lst (vl-sort lst
	 '(lambda (a b)
	    (cond
	      ((< (nth 3 a) (nth 3 b)))
	      ((= (nth 3 a) (nth 3 b)) 
		  (< (nth 4 a) (nth 4 b)))
	    )
	  )
))

 

 

0 Likes