Visual LISP, AutoLISP and General Customization

Visual LISP, AutoLISP and General Customization

Reply
Distinguished Contributor
Redraiderr2009
Posts: 164
Registered: ‎04-09-2008
Message 11 of 15 (170 Views)

Re: Sorting a List

01-18-2013 07:33 AM in reply to: Kent1Cooper
  (setq BlockDataBase
    '(
        (("00_CATEGORY_NUM" "CCC") ("BlockName" "Tree-03-08-CC8"))
	(("00_CATEGORY_NUM" "CCC") ("BlockName" "Tree-03-10-CC10"))
	(("00_CATEGORY_NUM" "AAA") ("BlockName" "Tree-02-08-QS3"))
	(("00_CATEGORY_NUM" "AAA") ("BlockName" "Tree-02-20-QS10"))
	(("00_CATEGORY_NUM" "SSS") ("BlockName" "Shrub-36-07-LPC"))
	(("00_CATEGORY_NUM" "SSS") ("BlockName" "Shrub-36-01-LP"))
	(("00_CATEGORY_NUM" "SSS") ("BlockName" "Shrub-36-03-L"))
	(("00_CATEGORY_NUM" "SSS") ("BlockName" "Shrub-30-07-KL"))
	(("00_CATEGORY_NUM" "SSS") ("BlockName" "Shrub-30-12-UP"))
	(("00_CATEGORY_NUM" "SSS") ("BlockName" "Shrub-30-08-TY"))
	(("00_CATEGORY_NUM" "HHH") ("BlockName" "Hatch-16-ATR@10"))
	(("00_CATEGORY_NUM" "HHH") ("BlockName" "Hatch-01-ZZ@4"))
	(("00_CATEGORY_NUM" "HHH") ("BlockName" "Hatch-05-AA@12"))
); list ); setq ; sort block data record alphabetically to put the category first ;; (setq BlockDataBase (vl-sort BlockDataBase '(lambda (A B) (cond ((< (cadar A) (cadar B))) ((= (cadar A) (cadar B)) (< (cadadr A) (cadadr B)) (< (substr (cadadr A) (+ (vl-string-position (ascii "-") (cadadr A) 0 T)2)) (substr (cadadr B) (+ (vl-string-position (ascii "-") (cadadr B) 0 T)2)) ) ) );_end cond );_end lambda );_end vl-sort );end setq

 

In the code above I am trying to sort this list and I need a way to get them to sort according to size. Please see the attached image to see the results of this sort. I basicially need "Tree-02-20-QS10" to come before "Tree-02-08-QS3". The sort will put the 1 (in ten) ahead of the 3 even though the 10 is a higher number than 3. I am thinking that if one has more charcters than the other then it should sort the list by character length. I do not know enough about list manipulation to accomplish this.  I am wondering if anyone has any insight into this or if someone has run into this and had a solution. 

 

Thanks in advance. 

 

Russell

Distinguished Contributor
Redraiderr2009
Posts: 164
Registered: ‎04-09-2008
Message 12 of 15 (153 Views)

Re: Sorting a List

01-18-2013 09:02 AM in reply to: Redraiderr2009

Sort of works but I am missing something.

 

(setq BlockDataBase
'(
(("00_CATEGORY_NUM" "CCC") ("BlockName" "Tree-03-08-CC8"))
(("00_CATEGORY_NUM" "CCC") ("BlockName" "Tree-03-10-CC10"))
(("00_CATEGORY_NUM" "CCC") ("BlockName" "Tree-03-06-CC12"))
(("00_CATEGORY_NUM" "AAA") ("BlockName" "Tree-02-08-QS3"))
(("00_CATEGORY_NUM" "AAA") ("BlockName" "Tree-02-22-QS13"))
(("00_CATEGORY_NUM" "AAA") ("BlockName" "Tree-02-20-QS10"))
(("00_CATEGORY_NUM" "GGG") ("BlockName" "Shrub-36-07-LPC"))
(("00_CATEGORY_NUM" "GGG") ("BlockName" "Shrub-36-01-LP"))
(("00_CATEGORY_NUM" "GGG") ("BlockName" "Shrub-36-03-L"))
(("00_CATEGORY_NUM" "GGG") ("BlockName" "Shrub-30-07-KL"))
(("00_CATEGORY_NUM" "GGG") ("BlockName" "Shrub-30-12-UP"))
(("00_CATEGORY_NUM" "GGG") ("BlockName" "Shrub-30-08-TY"))
(("00_CATEGORY_NUM" "HHH") ("BlockName" "Hatch-16-ATR@10"))
(("00_CATEGORY_NUM" "HHH") ("BlockName" "Hatch-01-ZZ@4"))
(("00_CATEGORY_NUM" "HHH") ("BlockName" "Hatch-05-AA@12"))
); list
); setq

(setq test
(vl-sort BlockDataBase
'(lambda (A B)
(cond
(
(< (nth 1 (nth 0 A)) (nth 1 (nth 0 B)))
)
(
(= (nth 1 (nth 0 A)) (nth 1 (nth 0 B)))
(< (nth 1 (nth 1 A)) (nth 1 (nth 1 B)))
(<
(substr (nth 1 (nth 1 A)) (+ (vl-string-position (ascii "-") (nth 1 (nth 1 A)) 0 T) 2))
(substr (nth 1 (nth 1 B)) (+ (vl-string-position (ascii "-") (nth 1 (nth 1 B)) 0 T) 2))
)
(<
(strlen (nth 1 (nth 1 A)))
(strlen (nth 1 (nth 1 B)))
)
)
)
)
)
)

*Expert Elite*
Kent1Cooper
Posts: 5,795
Registered: ‎09-13-2004
Message 13 of 15 (149 Views)

Re: Sorting a List

01-18-2013 09:13 AM in reply to: Redraiderr2009

Redraiderr2009 wrote:

 

... I need a way to get them to sort according to size. Please see the attached image to see the results of this sort. I basicially need "Tree-02-20-QS10" to come before "Tree-02-08-QS3". The sort will put the 1 (in ten) ahead of the 3 even though the 10 is a higher number than 3. I am thinking that if one has more charcters than the other then it should sort the list by character length. ....


Are the components following the last hyphen always two letters followed by numbers?  If so, it shouldn't be very hard to adjust the starting position of the (substr) to bypass those and just look at the numerical characters following.  Even if it may not always be two, it's possible to have any characters you list trimmed off, so you could designate the whole alphabet to eliminate one, or three, or however many, alphabetic characters.  But it would involve converting the remaining numerical characters into integers and comparing those values numerically, not as text strings alphabetically.

Kent Cooper
Distinguished Contributor
Redraiderr2009
Posts: 164
Registered: ‎04-09-2008
Message 14 of 15 (141 Views)

Re: Sorting a List

01-18-2013 10:44 AM in reply to: Kent1Cooper

I can say there are a minimum of two characters and then a size which can be 1 or 2 digit numbers. (Now watch .... someone will invent a reason to have a three digit number :smileyfrustrated :smileyhappy:. I would say that a three digiit number would be abnormal. 

 

Some examples of the data that I deal with.

***Tree blocks usually have two to three characters and have one to two digits

Tree-02-20-QV3

Tree-02-20-QV6

Tree-02-20-QV10

Tree-02-20-QV12

Tree-04-08-LIN8

Tree-04-10-LIN10

Tree-04-12-LIN12

*** Shrub blocks usually have no numbers but there are times for it

Shrub-36-02-IVN

Shrub-30-04-TA5

Shrub-36-08-TA10

**Hatch blocks are usually inserted with the hatch to provide the information needed.

Hatch-01-LM@12

Hatch-04-AA@8

Hatch-02-LMM@10

Hatch-11-ROPP@24

 

Active Contributor
AlessiMarc'Antonio
Posts: 49
Registered: ‎12-04-2006
Message 15 of 15 (122 Views)

Re: Sorting a List

01-19-2013 06:48 AM in reply to: Redraiderr2009

perhaps there is not this problem in your case but if you have to sort other kinds of lists
please note that vl-sort can delete elements that it sees as equal (maybe only if atoms):

(vl-sort
 '(3 2 1 3 1 2 2 2)
 '<
)
=> (1 2 3)

;  original by tony tanzillo (please note
;  the name change, i.e. "_" instead of "-")
(defun VL_Sort ( lst func )
      (mapcar
        '(lambda (x) (nth x lst))
         (vl-sort-i lst func)
      )
)

(VL_Sort
 '(3 2 1 3 1 2 2 2)
 '<
)
=> (1 1 2 2 2 2 3 3)

 

Marc'Antonio Alessi

http://alessi.xoom.it//alessi/Programmi.htm
(vl-string-translate "1234567890" "ie@mst.lan" "499825513610716")
2D Parametric for 2000-2013
Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Are You Going To Be @ AU 2014? Feel free to drop by our AU topic post and share your plans, plug a class that you're teaching, or simply check out who else from the community might be in attendance. Ohh and don't forgot to stop by the Autodesk Help | Learn | Collaborate booths in the Exhibit Hall and meet our community team if you get a chance!