Author Topic: Is there a versatile way sorting multi format string with chracters and numbers  (Read 2562 times)

0 Members and 1 Guest are viewing this topic.

jaydee

  • Guest
Hi.
Just wondering is there a vesatile way or function that could sort multi-formatted string with numbers, or do i have to write one for each format.

These are the string extracted from block attributes and the order i would them to appear, these are equipment labels and format is specify by the client.

("PC 5.01" "PC 5.02" "PC 5.10" "PC 6.01" "PC 6.11")

("PDU-NT5/2" "PDU-NT5/3" "PDU-NT6/1" "PDU-NT6/2" "PDU-NT6/11")

("ASTS NT5-01" "ASTS NT5-02" "ASTS NT5-11" "ASTS NT6-01" "ASTS NT6-11")

("TF-NT5-1" "TF-NT5-2" "TF-NT5-11" "TF-NT6-1" "TF-NT6-2" "TF-NT8-1")

("MDB-ST5/01" "MDB-ST5/02" "MDB-ST5/11" "MDB-ST5/21" "MDB-ST6/01" "MDB-ST6/11")

Thankyou

pBe

  • Bull Frog
  • Posts: 402
Hi.
Just wondering is there a vesatile way or function that could sort multi-formatted string with numbers, or do i have to write one for each format.

These are the string extracted from block attributes and the order i would them to appear, these are equipment labels and format is specify by the client.

("PC 5.01" "PC 5.02" "PC 5.10" "PC 6.01" "PC 6.11")

("PDU-NT5/2" "PDU-NT5/3" "PDU-NT6/1" "PDU-NT6/2" "PDU-NT6/11")

("ASTS NT5-01" "ASTS NT5-02" "ASTS NT5-11" "ASTS NT6-01" "ASTS NT6-11")

("TF-NT5-1" "TF-NT5-2" "TF-NT5-11" "TF-NT6-1" "TF-NT6-2" "TF-NT8-1")

("MDB-ST5/01" "MDB-ST5/02" "MDB-ST5/11" "MDB-ST5/21" "MDB-ST6/01" "MDB-ST6/11")

Thankyou

I can think of a few ways to approach this, you need to set an identifier for every format i.e. "." "/" "-" "/ and -" , also a flag for " 0" prefix all in one function

look into vl-sort function

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
This is the function written by gile used in my TabSort program to perform the 'Architectural Sort', I believe it will perform as required:

Code: [Select]
(defun _ArchSort ( lst / comparable ) ; (Gile)

    (defun comparable ( e1 e2 )
        (or
            (and (numberp e1) (numberp e2))
            (= 'STR (type e1) (type e2))
            (not e1)
            (not e2)
        )
    )
   
    (mapcar '(lambda ( x ) (nth x lst))
        (vl-sort-i (mapcar '_SplitStr lst)
            (function
                (lambda ( x1 x2 / n1 n2 comp )
                    (while
                        (and
                            (setq comp
                                (comparable (setq n1 (car x1)) (setq n2 (car x2)))
                            )
                            (= n1 n2)
                            (setq x1 (cdr x1))
                            (setq x2 (cdr x2))
                        )
                    )           
                    (if comp (< n1 n2) (numberp n1))
                )
            )
        )
    )
)

(defun _SplitStr ( str / lst test rslt num tmp ) ; (Gile)

    (setq lst  (vl-string->list str)
          test (chr (car lst))
    )
    (if (< 47 (car lst) 58)
        (setq num T)
    )
    (while (setq lst (cdr lst))
        (if num
            (cond
                (   (= 46 (car lst))
                    (if
                        (and
                            (cadr lst)
                            (setq tmp (strcat "0." (chr (cadr lst))))
                            (numberp (read tmp))
                        )
                        (setq rslt (cons (read test) rslt)
                              test tmp
                              lst  (cdr lst)
                        )
                        (setq rslt (cons (read test) rslt)
                              test "."
                              num nil
                        )
                    )
                )
                (   (< 47 (car lst) 58)
                    (setq test (strcat test (chr (car lst))))
                )
                (   t
                    (setq rslt (cons (read test) rslt)
                          test (chr (car lst))
                          num  nil
                    )
                )
            )
            (if (< 47 (car lst) 58)
                (setq rslt (cons test rslt)
                      test (chr (car lst))
                      num  T
                )
                (setq test (strcat test (chr (car lst))))
            )
        )
    )
    (if num
        (setq rslt (cons (read test) rslt))
        (setq rslt (cons test rslt))
    )   
    (reverse rslt)
)

Code: [Select]
_$ (_ArchSort '("PC 6.11" "PC 5.02" "PC 5.01" "PC 6.01" "PC 5.10"))
("PC 5.01" "PC 5.02" "PC 5.10" "PC 6.01" "PC 6.11")
_$
_$
_$ (_ArchSort '("PDU-NT6/2" "PDU-NT5/2" "PDU-NT6/11" "PDU-NT6/1" "PDU-NT5/3"))
("PDU-NT5/2" "PDU-NT5/3" "PDU-NT6/1" "PDU-NT6/2" "PDU-NT6/11")
_$
_$
_$ (_ArchSort '("ASTS NT6-01" "ASTS NT5-11" "ASTS NT5-02" "ASTS NT6-11" "ASTS NT5-01"))
("ASTS NT5-01" "ASTS NT5-02" "ASTS NT5-11" "ASTS NT6-01" "ASTS NT6-11")
_$
_$
_$ (_ArchSort '("TF-NT6-1" "TF-NT5-2" "TF-NT5-1" "TF-NT6-2" "TF-NT8-1" "TF-NT5-11"))
("TF-NT5-1" "TF-NT5-2" "TF-NT5-11" "TF-NT6-1" "TF-NT6-2" "TF-NT8-1")
_$
_$
_$ (_ArchSort '("MDB-ST6/11" "MDB-ST5/21" "MDB-ST5/02" "MDB-ST5/11" "MDB-ST5/01" "MDB-ST6/01"))
("MDB-ST5/01" "MDB-ST5/02" "MDB-ST5/11" "MDB-ST5/21" "MDB-ST6/01" "MDB-ST6/11")
« Last Edit: October 19, 2011, 08:02:49 AM by Lee Mac »

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Not as well written as Gile's but my old sort.  8-)
http://www.theswamp.org/index.php?topic=6474.0
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

jaydee

  • Guest
Thankyou Lee, Cab, pBe.
This is exactly what i want.

jaydee

  • Guest
Hi Lee and cab
Just would like to mention this little issue with _ArchSort where it fails if there is duplication in the list. I understand where the code intent to re-order layout tabs where its not possible to duplication tab names. But for me i use it for checking equipment used in layouts.

ie. this will fall over on acad 2006
Code: [Select]
(_ArchSort '("PC 5.01" "PC 5.01" "PC 6.11" "PC 5.02" "PC 6.01" "PC 5.10"))
where as Cabs code run successfully
Code: [Select]
(num_Sort '("PC 5.01" "PC 5.01" "PC 6.11" "PC 5.02" "PC 6.01" "PC 5.10"))
==>
("PC 5.01" "PC 5.01" "PC 5.02" "PC 5.10" "PC 6.01" "PC 6.11")

Thanks again Cab and Lee. Its a a very good piece of code

VVA

  • Newt
  • Posts: 166
My 5 cent
Quote
(SortStringWithNumberAsNumber '("PC 5.01" "PC 5.01" "PC 6.11" "PC 5.02" "PC 6.01" "PC 5.10") t)
===> ("PC 5.01" "PC 5.01" "PC 5.02" "PC 5.10" "PC 6.01" "PC 6.11")

Search of Windows type Sort function

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Just would like to mention this little issue with _ArchSort where it fails if there is duplication in the list.

Thanks for reporting that  :-)

I have updated the above code.

jaydee

  • Guest
Hi.
Also one more question i would like to ask. Thankyou in advance, I wish i could figure it out myself.

The code below will append "-" if the next integer number are greater then last more then 1 (gap between integer numbers)
Code: [Select]
(defun NumberCheck (lst / result diff)
 (setq result (list (car lst))
       lst    (cdr lst)
 )
 (while (car lst)
  (if (> (- (atoi (substr (car lst) 2))
    (atoi (substr (last result) 2))
)
1
      )
   (setq result (append result (list "-" (car lst))))
   (setq result (append result (list (car lst))))
  )
  (setq lst (cdr lst))
 )
 result
)
Code: [Select]
(NumberCheck '("P1" "P3" "P4" "P5" "P17" "P18" "P19" "P23" "P24" "P25"))
===>
("P1" "-" "P3" "P4" "P5" "-" "P17" "P18" "P19" "-" "P23" "P24" "P25")

But for these multi-formated such as these list below, how could i append "-" in between string if the next label in greater then 1
ie.
("ASTS NT5-01" "ASTS NT5-02" "ASTS NT5-11" "ASTS NT5-12" "ASTS NT6-11")
===>
("ASTS NT5-01" "ASTS NT5-02" "-" "ASTS NT5-11" "ASTS NT5-12" "-" "ASTS NT6-11")


Code: [Select]
("PC 5.01" "PC 5.02" "PC 5.10" "PC 6.01" "PC 6.11")
("PDU-NT5/2" "PDU-NT5/3" "PDU-NT6/1" "PDU-NT6/2" "PDU-NT6/11")
("ASTS NT5-01" "ASTS NT5-02" "ASTS NT5-11" "ASTS NT5-12" "ASTS NT6-11")
("TF-NT5-1" "TF-NT5-2" "TF-NT5-11" "TF-NT6-1" "TF-NT6-2" "TF-NT8-1")
("MDB-ST5/01" "MDB-ST5/02" "MDB-ST5/11" "MDB-ST5/21" "MDB-ST6/01" "MDB-ST6/11")
« Last Edit: October 19, 2011, 08:20:16 AM by jaydee »

jaydee

  • Guest
Thankyou VVA, that seems to be another verygood sorting function.
Thankyou Lee for the update.

jaydee

  • Guest
Hi.
Please assist with argument in function. Im struggling getting this to work.
How to provide (car lst) and (last result) in the function below as an argument, if I run ( get#fromMixedStr "PC-1.01XY") will return value

Thankyou. Been playing this code all night with lots of trial/error thingy. I finally figure it out, it was the list not being localised, therefore the list just keep building up.

101
Code: [Select]
;;extract number from selected text
;;By Andrea Andreetti
;;12/05/2001
(defun addnum ()
(if (= num nil)
 (setq num "")
)
(setq num (strcat num ftxt))
)
;;;--------------------
(defun get#fromMixedStr (lst1 / len1 val ftxt)
;;;(setq mixedstr "PC-1.01XY")
(setq len1 (strlen lst1))
(setq val 1)
(repeat len1
 (progn
  (setq ftxt (substr lst1 val 1))
   (if (= ftxt ".")
    (setq ftxt "")
   )
   (if (numberp (read ftxt))
    (addnum)
   )
   (setq val (+ val 1))
   num
 )
)
)
The result i would like
(setq lst '("PDU-NT5/2" "PDU-NT5/3" "PDU-NT6/1" "PDU-NT6/2" "PDU-NT6/11"))
===>
(setq lst '("PDU-NT5/2" "PDU-NT5/3" "-" "PDU-NT6/1" "PDU-NT6/2" "-" "PDU-NT6/11"))

therefor i think my problem is the argument in the function
(get#fromMixedStr (car lst))
(get#fromMixedStr (last result))


Code: [Select]
(defun NumberCheck2 (lst / result diff)
 (setq result (list (car lst))
          lst (cdr lst)
 )
 (while (car lst)
  (if
   (> (- (atoi (get#fromMixedStr (car lst)))
       (atoi (get#fromMixedStr (last result))))
     1
   )
   (setq result (append result (list "-" (car lst))))
   (setq result (append result (list (car lst))))
  )
  (setq lst (cdr lst))
 )
 result
)
« Last Edit: October 20, 2011, 09:16:12 AM by jaydee »