Alphanumeric sort

Alphanumeric sort

drew_dewit
Advocate Advocate
1,880 Views
8 Replies
Message 1 of 9

Alphanumeric sort

drew_dewit
Advocate
Advocate

I am looking to sort the following list ("U20" "U10" "U110" "U11" "T1" "V1") to first be sorted alphabetically then numerically so that it ends up being ("T1" "U10" "U11" "U20" "U110" "V1")  this is the funtion I am currently using

 

(defun sort (l)
(defun sortFunc (m n)
(< (car m) (car n))
)
(vl-sort l 'sortFunc)
)

 

This works fine till you get to a 3 digit number then it tries to do ("T1" "U10" "U11" "U110" "U20" "V1").

 

Any suggestions?

0 Likes
1,881 Views
8 Replies
Replies (8)
Message 2 of 9

pbejse
Mentor
Mentor

@drew_dewit wrote:

I am looking to sort the following list ("U20" "U10" "U110" "U11" "T1" "V1") to first be sorted alphabetically then

Any suggestions?


Suggestion: You need to split them so you can effectively sort the numeric values.

Let us know if you need help with that.

 

 

0 Likes
Message 3 of 9

drew_dewit
Advocate
Advocate

That would be, I figured that was the route to go but don't have a good grasp on the best way to do that.

0 Likes
Message 4 of 9

hak_vz
Advisor
Advisor

As @pbejse  suggests

 

 

(setq lst '("U20" "U10" "U110" "U11" "T1" "V1"))
(foreach e lst(setq ret (cons (list (substr e 1 1)(atoi(substr e 2)))ret)))

 

New list ret is then

 

(("V" 1) ("T" 1) ("U" 11) ("U" 110) ("U" 10) ("U" 20))

 

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 5 of 9

Kent1Cooper
Consultant
Consultant

If they always start with a single letter followed by only numbers representing integers, this seems to work:

 

(defun SortAI (lst); = Sort Alphabetically, and within that by Integer value
  (vl-sort
    (vl-sort lst '(lambda (a b) (< (atoi (substr a 2)) (atoi (substr b 2)))))
    '(lambda (c d) (< (substr c 1 1) (substr d 1 1)))
  )
)

 

It sorts by the numbers "inside," ignoring the letters and using numerical rather than alphabetical values for the numbers, then "outside" sorts that result by the initial letters, and those entries that share an initial letter stay, among themselves, in the order from the numerically-sorted result.

 

(setq lst '("U20" "U10" "U110" "U11" "T1" "V1"))

(SortAI lst)
  ("T1" "U10" "U11" "U20" "U110" "V1")

 

(setq lst '("F123" "T4" "A23" "Q3450" "F13" "A8" "T1"))

(SortAI lst)

  ("A8" "A23" "F13" "F123" "Q3450" "T1" "T4")

Kent Cooper, AIA
Message 6 of 9

pbejse
Mentor
Mentor

@drew_dewit wrote:

That would be, I figured that was the route to go but don't have a good grasp on the best way to do that.


One example

(defun _n (str / s)
  (setq s (vl-string-right-trim "0123456789" str))
  (list s (atoi (substr str (1+ (strlen s)))))
)

_$ (_n "U101")
("U" 101)
_$ (_n "UBN101")
("UBN" 101)

 

(Defun sortFunc (l)
(Vl-sort l'(lambda (n m)
		(setq n (_n n) m (_n m))
			(cond
			  ((< (Car n) (car m)))
			  ((eq (Car n) (car m)) (< (Cadr n) (cadr m)))
			)
		)
	 )
)

_$ (setq lst '("U20" "U10" "U110" "U11" "T1" "V1"))
("U20" "U10" "U110" "U11" "T1" "V1")
_$ (Acad_strlsort lst)
("T1" "U10" "U11" "U110" "U20" "V1")
_$ (sortFunc lst)
("T1" "U10" "U11" "U20" "U110" "V1")

 

_$ (setq lst '("U20" "U10" "U110" "U11" "T1" "V1" "HE110" "HE250" "HE2"))
("U20" "U10" "U110" "U11" "T1" "V1" "HE110" "HE250" "HE2")
_$ (Acad_strlsort lst)
("HE110" "HE2" "HE250" "T1" "U10" "U11" "U110" "U20" "V1")
_$ (sortFunc lst)
("HE2" "HE110" "HE250" "T1" "U10" "U11" "U20" "U110" "V1")

 

HTH

 

Message 7 of 9

drew_dewit
Advocate
Advocate

Thanks guys,

@Kent1Cooper 

So this function works

(defun SortAI (lst); = Sort Alphabetically, and within that by Integer value
  (vl-sort
    (vl-sort lst '(lambda (a b) (< (atoi (substr a 2)) (atoi (substr b 2)))))
    '(lambda (c d) (< (substr c 1 1) (substr d 1 1)))
  )
)

 

However I was wrong in how the list is presented to the function. Its actually a list of lists. So it looks like (("A10" Description" "Rev")("B100" "Description" "Rev" ...)

 

How can i modify this to sort by the first element of the sub lists. I imagine I can insert a CAR but I'm not sure the best way.

0 Likes
Message 8 of 9

Kent1Cooper
Consultant
Consultant

@drew_dewit wrote:

... I was wrong in how the list is presented to the function. Its actually a list of lists. So it looks like (("A10" Description" "Rev")("B100" "Description" "Rev" ...)

 

How can i modify this to sort by the first element of the sub lists. I imagine I can insert a CAR but I'm not sure the best way.


I hope this will do that [untested]:


(defun SortAI (lst); = Sort Alphabetically, and within that by Integer value [of first element]
  (vl-sort
    (vl-sort lst '(lambda (a b) (< (atoi (substr (car a) 2)) (atoi (substr (car b) 2)))))
    '(lambda (c d) (< (substr (car c) 1 1) (substr (car d) 1 1)))
  )
)

Kent Cooper, AIA
0 Likes
Message 9 of 9

pbejse
Mentor
Mentor

@drew_dewit wrote:

How can i modify this to sort by the first element of the sub lists. I imagine I can insert a CAR but I'm not sure the best way.


FWIW:

(defun _n (str / s)
(setq s (vl-string-right-trim "0123456789" str))
(list s (atoi (substr str (1+ (strlen s)))))
)

(Defun ThisFunc (l) (Vl-sort l'(lambda (n m) (setq n (_n (Car n)) m (_n (Car m))) (cond ((< (Car n) (car m))) ((eq (Car n) (car m)) (< (Cadr n) (cadr m))) ) ) ) )
(setq lst '(("A10" "Description" "Rev")("U20" "Description" "Rev")("B100" "Description" "Rev")
	    ("U10" "Description" "Rev")("HE110" "Description" "Rev")("U110" "Description" "Rev")
	    ("HE2" "Description" "Rev")))

(ThisFunc lst)

("A10" "Description" "Rev") ("B100" "Description" "Rev") ("HE2" "Description" "Rev")
("HE110" "Description" "Rev")("U10" "Description" "Rev") ("U20" "Description" "Rev")
("U110" "Description" "Rev") 

 

0 Likes