Jump to content

Help in Sorting List By Sublist


Engineer_Yasser

Recommended Posts

I have list

 

(
(<Entity name: 21b0e473810> . "R-4-2-16.00")
(<Entity name: 21b0e473a90> . "R-11-16.00")
(<Entity name: 21b7741fd90> . "CL-2-18.00")
(<Entity name: 21b0e473910> . "R-8-16.00")
(<Entity name: 21b7741fd10> . "CL-17-20.00")
(<Entity name: 21b0e473990> . "R-9-20.00")
(<Entity name: 21b7741fe90> . "R-4-1-16.00")
(<Entity name: 21b7741ff10> . "R-4-1-20.00")
(<Entity name: 21b0e473890> . "R-7-20.00")
(<Entity name: 21b7741fe10> . "R-4-15.00")
(<Entity name: 21b0e473a10> . "R-10-20.00")
(<Entity name: 21b0e473b10> . "R-1-20.00")
)

 

 

I want to be sorted out like

 

(
(<Entity name: 21b7741fd90> . "CL-2-18.00")
(<Entity name: 21b7741fd10> . "CL-17-20.00")
(<Entity name: 21b0e473b10> . "R-1-20.00")
(<Entity name: 21b7741fe10> . "R-4-15.00")
(<Entity name: 21b7741fe90> . "R-4-1-16.00")
(<Entity name: 21b7741ff10> . "R-4-1-20.00")
(<Entity name: 21b0e473810> . "R-4-2-16.00")
(<Entity name: 21b0e473890> . "R-7-20.00")
(<Entity name: 21b0e473910> . "R-8-16.00")
(<Entity name: 21b0e473990> . "R-9-20.00")
(<Entity name: 21b0e473a10> . "R-10-20.00")
(<Entity name: 21b0e473a90> . "R-11-16.00")

)

 

when I tried vl-sort i didn't get the correct result

Edited by Engineer_Yasser
Link to comment
Share on other sites

In the comparison function supplied to vl-sort, split the cdr of each dotted pair using the hyphen as a delimiter and then compare each element. Or, alternatively (and likely more performant), sort a version of the list (which has already been tokenised) using vl-sort-i and then use mapcar to sort the original list.

Edited by Lee Mac
Link to comment
Share on other sites

Im guessing your sort looked something like this? you need to add 0's to the single digit numbers

 

(<Entity name: 21b7741fd10> . "CL-17-20.00")
(<Entity name: 21b7741fd90> . "CL-2-18.00")
(<Entity name: 21b0e473b10> . "R-1-20.00")
(<Entity name: 21b0e473a10> . "R-10-20.00")
(<Entity name: 21b0e473a90> . "R-11-16.00") 
(<Entity name: 21b7741fe10> . "R-4-15.00")
(<Entity name: 21b7741fe90> . "R-4-1-16.00")
(<Entity name: 21b7741ff10> . "R-4-1-20.00")
(<Entity name: 21b0e473810> . "R-4-2-16.00")
(<Entity name: 21b0e473890> . "R-7-20.00")
(<Entity name: 21b0e473910> . "R-8-16.00")
(<Entity name: 21b0e473990> . "R-9-20.00")

 

this will add 0's but your going to have to split up the string to do it then strcat it back together.

https://www.cadtutor.net/forum/topic/78351-help-with-routinenumerical-filter/?do=findComment&comment=623332

(AT:NumFix num 2)

 

(<Entity name: 21b7741fd90> . "CL-02-18.00")
(<Entity name: 21b7741fd10> . "CL-17-20.00")
...
(<Entity name: 21b0e473b10> . "R-01-20.00")
(<Entity name: 21b7741fe10> . "R-04-15.00")
...
(<Entity name: 21b0e473a10> . "R-10-20.00")
(<Entity name: 21b0e473a90> . "R-11-16.00") 

 

Link to comment
Share on other sites

9 minutes ago, Lee Mac said:

Or, alternatively (and likely more performant), sort a version of the list (which has already been tokenised) using vl-sort-i and then use mapcar to sort the original list.

 

Perhaps something like this -

(defun sortit ( lst )
    (mapcar '(lambda ( n ) (nth n lst))
        (vl-sort-i (mapcar '(lambda ( x ) (LM:str->lst (cdr x) "-")) lst)
            (function
                (lambda ( a b / x y )
                    (while (and a b (= (car a) (car b)))
                        (setq a (cdr a)
                              b (cdr b)
                        )
                    )
                    (cond
                        (   (null a))
                        (   (null b) nil)
                        (   (and (numberp (setq x (read (car a))))
                                 (numberp (setq y (read (car b))))
                            )
                            (< x y)
                        )
                        (   (numberp x))
                        (   (numberp y) nil)
                        (   (< (car a) (car b)))
                    )
                )
            )
        )
    )
)

;; String to List  -  Lee Mac
;; Separates a string using a given delimiter
;; str - [str] String to process
;; del - [str] Delimiter by which to separate the string
;; Returns: [lst] List of strings
 
(defun LM:str->lst ( str del / pos )
    (if (setq pos (vl-string-search del str))
        (cons (substr str 1 pos) (LM:str->lst (substr str (+ pos 1 (strlen del))) del))
        (list str)
    )
)

 

 

  • Thanks 1
Link to comment
Share on other sites

19 minutes ago, mhupp said:

Im guessing your sort looked something like this? you need to add 0's to the single digit numbers

 

(<Entity name: 21b7741fd10> . "CL-17-20.00")
(<Entity name: 21b7741fd90> . "CL-2-18.00")
(<Entity name: 21b0e473b10> . "R-1-20.00")
(<Entity name: 21b0e473a10> . "R-10-20.00")
(<Entity name: 21b0e473a90> . "R-11-16.00") 
(<Entity name: 21b7741fe10> . "R-4-15.00")
(<Entity name: 21b7741fe90> . "R-4-1-16.00")
(<Entity name: 21b7741ff10> . "R-4-1-20.00")
(<Entity name: 21b0e473810> . "R-4-2-16.00")
(<Entity name: 21b0e473890> . "R-7-20.00")
(<Entity name: 21b0e473910> . "R-8-16.00")
(<Entity name: 21b0e473990> . "R-9-20.00")

 

this will add 0's but your going to have to split up the string to do it then strcat it back together.

https://www.cadtutor.net/forum/topic/78351-help-with-routinenumerical-filter/?do=findComment&comment=623332

(AT:NumFix num 2)

 

(<Entity name: 21b7741fd90> . "CL-02-18.00")
(<Entity name: 21b7741fd10> . "CL-17-20.00")
...
(<Entity name: 21b0e473b10> . "R-01-20.00")
(<Entity name: 21b7741fe10> . "R-04-15.00")
...
(<Entity name: 21b0e473a10> . "R-10-20.00")
(<Entity name: 21b0e473a90> . "R-11-16.00") 

 

 

 

Thanks For Help 🌺

 

 

  • Like 1
Link to comment
Share on other sites

8 minutes ago, Lee Mac said:

 

Perhaps something like this -

(defun sortit ( lst )
    (mapcar '(lambda ( n ) (nth n lst))
        (vl-sort-i (mapcar '(lambda ( x ) (LM:str->lst (cdr x) "-")) lst)
            (function
                (lambda ( a b / x y )
                    (while (and a b (= (car a) (car b)))
                        (setq a (cdr a)
                              b (cdr b)
                        )
                    )
                    (cond
                        (   (null a))
                        (   (null b) nil)
                        (   (and (numberp (setq x (read (car a))))
                                 (numberp (setq y (read (car b))))
                            )
                            (< x y)
                        )
                        (   (numberp x))
                        (   (numberp y) nil)
                        (   (< (car a) (car b)))
                    )
                )
            )
        )
    )
)

;; String to List  -  Lee Mac
;; Separates a string using a given delimiter
;; str - [str] String to process
;; del - [str] Delimiter by which to separate the string
;; Returns: [lst] List of strings
 
(defun LM:str->lst ( str del / pos )
    (if (setq pos (vl-string-search del str))
        (cons (substr str 1 pos) (LM:str->lst (substr str (+ pos 1 (strlen del))) del))
        (list str)
    )
)

 

 

 

Perfect Solution .. You are Genius  😍 🌹

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...