Lisp : Reorder a LIST containing multiple LISTS by the elements contained in the lists

Lisp : Reorder a LIST containing multiple LISTS by the elements contained in the lists

roland.ifrene3T43E
Explorer Explorer
1,194 Views
7 Replies
Message 1 of 8

Lisp : Reorder a LIST containing multiple LISTS by the elements contained in the lists

roland.ifrene3T43E
Explorer
Explorer

Hello world !

 

I'm having trouble sorting a list of layers names by the contents of said layers names. 

 

Some context

 

I have a modeless dialog in which I can create layers based on predetermined lists or text boxes.

The final goal is to extract information from the polylines of the created layers. Information contained in a legend.

What I would like is to sort my legend according to my "lists" "Type" and "Dalle/Slab" (see modeless form). So at the top i will have all the "Plancher" ones, then "Platelage"...

 

rolandifrene3T43E_0-1631106843015.png
____________________________________________

 

I have looked at a few posts on this forum and others, about sorting lists containing lists. But nothing that sorts a list (A) containing lists (B) according to the contents of the lists (B). (if the content isnt numbers or "strings" where i can run a "basic" sort fonction)

Currently, I get my legend by running a loop on a list that contains all the layers of selected polylines. Inside my loop and with the help of Lee-Mac's code that allows me to transform a string into a list. I transform my layer name in several elements that I assign to different variables. "ACE-DQE_Level_Type_Slab_Thickness_Height_Support_Hatch". Those elements or variables i assign to my legend bloc and then increment my loop and run it again.

 

Before making my loop I would like to have my A list sorted by "Type" then by "Dalle/Slab" and finally by color.
The type sort order being (Plancher>Poutre>Rampe>...>Palier)
The slab sort order being (CEP>...)
The color sort order being (Bleu (5) > Rouge (1) > Vert (3)> ...).

(For the colors i need to retrieve the layer color with the string name X but i dont think it's an essential addition)

 

Being a beginner on the LISP language, openDCL I don't see how I could proceed in order to realize this.

 

If some of you can help me, even if it's only by giving me some ideas, I would be grateful.

 

(defun c:BetonCADLegende ( /)
(ACE:init)
(setvar "OSMODE" 0)
(setq ls (ACE:BetonCadMajSurface)) ;; I retrieve my list of layers
;; Thats's where i think i will reorder my layer list (ls)
(setvar "osmode" 8)
(setq pt (getpoint "\nPoint de départ de la nomenclature...")) ;;Starting point of the legend
(setq ix 0)
(repeat (length ls)
(setq nomcalque (car (nth ix ls)))
(setvar "clayer" nomcalque)
(setq vsurface (rtos (/ (cadr (nth ix ls)) 10000) 2 0))
(setq pt2 (list (+ 255 (car pt)) (- (cadr pt) 112.5)))
(command-s "rectangle" "H" "0" "L" "0" pt pt2)
(setq ent (entlast))
(if (vl-string-search "ACE-DQE" nomcalque)
(progn
(defun Str2Lst ( s d / p ) ;; LeeMac String to list
(if (setq p (vl-string-search d s))
(cons (substr s 1 p) (Str2Lst (substr s (+ p 1 (strlen d))) d)) (list s))
)
(setq CalqueLst (Str2Lst nomcalque "_"))
(setq T_Nvx (nth 1 CalqueLst))
(setq T_Type (nth 2 CalqueLst))
(setq T_Dalle (nth 3 CalqueLst))
(setq T_EP (vl-string-translate "." "," (nth 4 CalqueLst)))
(setq T_HT (vl-string-translate "." "," (nth 5 CalqueLst)))
(setq T_App (vl-string-translate "-" "/" (nth 6 CalqueLst)))
(setq T_Hatch (nth 7 CalqueLst))
)
)
(if (= T_Hatch "SOLID") (command "-hachures" "p" T_Hatch "s" ent "" ""))
(if (= T_Hatch "45") (command "-hachures" "p" "U" T_Hatch "30" "N" "s" ent "" "" ))
(if (= T_Hatch "135") (command "-hachures" "p" "U" T_Hatch "30" "N" "s" ent "" "" ))
(if (= T_Hatch "ZIGZAG") (command "-hachures" "p" T_Hatch "10" "0" "s" ent "" "" ))
(if (= T_Hatch "ANSI37") (command "-hachures" "p" T_Hatch "10" "0" "s" ent "" "" ))
(if (= T_Hatch "HONEY") (command "-hachures" "p" T_Hatch "10" "0" "s" ent "" "" ))
(if (= T_Hatch "AR-HBONE") (command "-hachures" "p" T_Hatch "0.5" "0" "s" ent "" "" ))

(setvar "attreq" 0)
(setq ptleg (list (+ 290 (car pt )) (cadr pt)))
(command "inserer" "NomenclatureBetonCad" ptleg "2" "2" "0")
(setq ent (entlast))
(setvar "attreq" 1)
(if
(and (= T_Type "Plancher") (= T_App "escalier"))
(ACE:BetonCadMajAtt ent "L1" (strcat "Fermeture d'escalier " T_Dalle))
(if
(and (= T_Type "Platelage") (= T_Dalle "circulation"))
(ACE:BetonCadMajAtt ent "L1" T_Type)
(ACE:BetonCadMajAtt ent "L1" (strcat T_Type " " T_Dalle))
)
)
(if
(and (= T_Type "Platelage") (= T_Dalle "support de banche"))
(ACE:BetonCadMajAtt ent "L2" (strcat "Banche HT: " T_EP))
(if
(or (= T_Type "Poutre") (and (= T_Type "Platelage") (= T_Dalle "poutre CEP")))
(ACE:BetonCadMajAtt ent "L2" (strcat "Section: " T_EP))
(ACE:BetonCadMajAtt ent "L2" (strcat "Epaisseur de dalle: " T_EP))
)
)
(if
(= T_App "réhausse")
(ACE:BetonCadMajAtt ent "L3" (strcat "Hauteur réhaussage: " T_HT))
(if
(= T_Type "Platelage")
(ACE:BetonCadMajAtt ent "L3" (strcat "Hauteur sous platelage: " T_HT))
(if
(= T_Type "Poutre")
(ACE:BetonCadMajAtt ent "L3" (strcat "Hauteur sous poutre: " T_HT))
(ACE:BetonCadMajAtt ent "L3" (strcat "Hauteur sous dalle: " T_HT))
)
)
)
(if
(= T_App "réhausse")
(ACE:BetonCadMajAtt ent "L4" "Réhaussage PH N-1")
(ACE:BetonCadMajAtt ent "L4" (strcat "Appui sur " T_App))
)
(if
(and (= T_Type "Poutre") (= T_Dalle "préfa"))
(ACE:BetonCadMajAtt ent "L5" (strcat "Quantité: " vsurface " ù"))
(if
(or (and (= T_Type "Poutre") (= T_Dalle "CEP")) (= T_Type "Casquette"))
(ACE:BetonCadMajAtt ent "L5" (strcat "Lineaire: " vsurface " ml"))
(ACE:BetonCadMajAtt ent "L5" (strcat "Surface: " vsurface " m²"))
)
)
(setq ptnvx (list (+ (car pt ) 127.5) (+ (cadr pt) 20)))
(command-s "_LAYER" "e" "ACE - Papier" "CO" "4" "ACE - Papier" "T" "a" "ACE - Papier" "s" "NON TRACE - Fenetre pres" "ACE - Papier" "o" "")
(command-s "-MTEXT" ptnvx "J" "BC" "H" "30" "R" "" ptnvx T_Nvx "")
(setq pt (list (car pt ) (- (cadr pt) 475)))
(setq ix (+ ix 1))
)
(ACE:end)
)

 

 

 

0 Likes
1,195 Views
7 Replies
Replies (7)
Message 2 of 8

pbejse
Mentor
Mentor

There's just way too many information to digest. to make it simpler and easy for us, please post a sample of the list to be sorted?  and its preferred result.

 

0 Likes
Message 3 of 8

Kent1Cooper
Consultant
Consultant

@roland.ifrene3T43E wrote:

.... sorts a list (A) containing lists (B) according to the contents of the lists (B). (if the content isnt numbers or "strings" where i can run a "basic" sort fonction)

....


It will probably involve making a list of the order of things you want to sort by if that will not be alphabetical or numerical order, and sort the list of sub-lists by finding the position of a part of a sub-list in the sort-by list.  For example:

 

(setq

  RefList '("One" "Two" "Three" "Four" "Five" "Six"); items to sort by in desired [non-alphabetical] order

  ListToSort '(("Two" "no") ("Six" "never") ("Three" "maybe") ("One" "yes") ("Five" "sometimes") ("Four" "always")); disordered

)

Then:

(vl-sort ListToSort '(lambda (x y) (< (vl-position (car x) RefList) (vl-position (car y) RefList))))

returns:
(("One" "yes") ("Two" "no") ("Three" "maybe") ("Four" "always") ("Five" "sometimes") ("Six" "never")); in sort-by order of first items

 

Sorting further among sub-lists with the same first sorting entry, by comparing other entries, might require dividing up the overall list into sub-sets and doing this kind of sorting within each, based on the other entries and different sort-by lists, before putting them all back together, presumably with (append).

Kent Cooper, AIA
0 Likes
Message 4 of 8

Sea-Haven
Mentor
Mentor

I have sort up to 5 levels deep it involves a sort sort sort function.

 

(cond
((= (- numcols 1) 1)(setq lst (complex-sort lst '((< . 0)))))
((= (- numcols 1)  2)(setq lst (complex-sort lst '((< . 0) (< . 1)))))
((= (- numcols 1)  3)(setq lst (complex-sort lst '((< . 0) (< . 1) (< . 2)))))
((= (- numcols 1)  4)(setq lst (complex-sort lst '((< . 0) (< . 1) (< . 2)(< . 3)))))
((=  (- numcols 1)  5)(setq lst (complex-sort lst '((< . 0) (< . 1) (< . 2)(< . 3)(< . 4)))))
((> (- numcols 1)  5)(setq lst (complex-sort lst '((< . 0) (< . 1) (< . 2)(< . 3)(< . 4)))))
)

 

No idea if it will work with what you have. waiting for a lst or dwg.

0 Likes
Message 5 of 8

roland.ifrene3T43E
Explorer
Explorer

Hi, thanks for the replies !

Here is the initial list.

 

 

("ACE-DQE_PH R+1_Rampe_CEP_20 cm_2.57 m_dalle béton_45" 
"ACE-DQE_PH R+1_Poutre_CEP_20 cm_2.57 m_dalle béton_45" 
"ACE-DQE_PH R+1_Platelage_support de banche_20 cm_2.57 m_dalle béton_45" 
"ACE-DQE_PH R+1_Platelage_poutre CEP_20 cm_2.57 m_dalle béton_45" 
"ACE-DQE_PH R+1_Plancher_prédalles_20 cm_2.57 m_dalle béton_45" 
"ACE-DQE_PH R+1_Plancher_CEP_20 cm_2.57 m_dalle béton_45" 
"ACE-DQE_PH R+1_Plancher_alvéolaire_20 cm_2.57 m_dalle béton_45" 
"ACE-DQE_PH R+1_Plancher_+ voile_20 cm_2.57 m_dalle béton_45" 
"ACE-DQE_PH R+1_Palier d'escalier_CEP_20 cm_2.57 m_dalle béton_45" 
"ACE-DQE_PH R+1_Casquette_CEP_20 cm_2.57 m_dalle béton_45" 
"ACE-DQE_PH R+1_Balcon Débord_CEP_20 cm_2.57 m_dalle béton_45")

 


Here the desired order of said list

 

("ACE-DQE_PH R+1_Plancher_CEP_20 cm_2.57 m_dalle béton_45"
"ACE-DQE_PH R+1_Plancher_prédalles_20 cm_2.57 m_dalle béton_45" 
"ACE-DQE_PH R+1_Plancher_alvéolaire_20 cm_2.57 m_dalle béton_45" 
"ACE-DQE_PH R+1_Plancher_+ voile_20 cm_2.57 m_dalle béton_45"
"ACE-DQE_PH R+1_Balcon Débord_CEP_20 cm_2.57 m_dalle béton_45"
"ACE-DQE_PH R+1_Poutre_CEP_20 cm_2.57 m_dalle béton_45" 
"ACE-DQE_PH R+1_Platelage_support de banche_20 cm_2.57 m_dalle béton_45" 
"ACE-DQE_PH R+1_Platelage_poutre CEP_20 cm_2.57 m_dalle béton_45"
"ACE-DQE_PH R+1_Casquette_CEP_20 cm_2.57 m_dalle béton_45"
"ACE-DQE_PH R+1_Palier d'escalier_CEP_20 cm_2.57 m_dalle béton_45"
"ACE-DQE_PH R+1_Rampe_CEP_20 cm_2.57 m_dalle béton_45")

 

 

It clicked on the way home though :

(defun StringToList ( s d / p ) ;; LeeMac String to list

(if (setq p (vl-string-search d s))
(cons (substr s 1 p) (StringToList (substr s (+ p 1 (strlen d))) d)) (list s))

)
(setq i 0)

(repeat (length InitialList)

(setq CurrentLayer (nth i InitialList))
(if (vl-string-search "ACE-DQE" CurrentLayer)

(progn

(setq ListCurLayer (StringToList CurrentLayer "_"))
(if (= (nth 2 ListCurLayer) "Plancher")

(progn

(if (= (nth 3 ListCurLayer) "CEP")
(setq ListType1A (cons CurrentLayer ListType1A))
(setq ListType1B (cons CurrentLayer ListType1B)))
(setq ListType1 (append ListType1A (reverse ListType1B))))

(if (= (nth 2 ListCurLayer) "Balcon Débord")

(setq ListType2 (cons CurrentLayer ListType2))
(if (= (nth 2 ListCurLayer) "Poutre")

(setq ListType3 (cons CurrentLayer ListType3))
(if (= (nth 2 ListCurLayer) "Platelage")

(setq ListType4 (cons CurrentLayer ListType4))

(if (= (nth 2 ListCurLayer) "Casquette")
(setq ListType5 (cons CurrentLayer ListType5))

(if (= (nth 2 ListCurLayer) "Palier d'escalier")
(setq ListType6 (cons CurrentLayer ListType6))

(if (= (nth 2 ListCurLayer) "Rampe")
(setq ListType7 (cons CurrentLayer ListType7)))))))))))

(setq i (+ i 1))

)

(setq ListSorted (append ListType1 ListType2 ListType3 ListType4 ListType5 ListType6 ListType7))

It gets the job done, but i'll look at your codes and get back to you guys !

 

0 Likes
Message 6 of 8

pbejse
Mentor
Mentor

On your example desired result

I can see that you also set a condition if the 3rd item is "Plancher"  but you did not do the same for "Platelage"?

 

Are you also tellings us the value of initialist variable varies?  I assume that it is otherwise you dont need to run a program to sort it, in that case you do need to set a condition if the  target is the same at first level.

 

I'm looking at this list where the top level is the same but the order does not make sense ( I cannot make sense of it rather)

 

 

("ACE-DQE" "PH R+1" "Plancher" "CEP" "20 cm" "2.57 m" "dalle béton" "45") 
("ACE-DQE" "PH R+1" "Plancher" "prédalles" "20 cm" "2.57 m" "dalle béton" "45") 
("ACE-DQE" "PH R+1" "Plancher" "alvéolaire" "20 cm" "2.57 m" "dalle béton" "45") 
("ACE-DQE" "PH R+1" "Plancher" "+ voile" "20 cm" "2.57 m" "dalle béton" "45")

 

and

 

("ACE-DQE" "PH R+1" "Platelage" "support de banche" "20 cm" "2.57 m" "dalle béton" "45") 
("ACE-DQE" "PH R+1" "Platelage" "poutre CEP" "20 cm" "2.57 m" "dalle béton" "45")

 

Thoughts?

 

0 Likes
Message 7 of 8

roland.ifrene3T43E
Explorer
Explorer

Yes the InitialList is just an exemple of what the list could be. The InitialList is a list of layers that look like this (ACE-DQE_LevelVariable_TypeVariable_SlabVariable_ThicknessVariable_HeightVariable_SupportVariable_HatchType) Those variables are filled in a modeless form.

 

I put an additionnal condition for the 3rd Item "Plancher" because the ordre that i want to get from it is (*_Plancher_CEP_* > *_Plancher_prédalles_* > *_Plancher_alvéolaire_* > *_Plancher_+ voile_* > *_Plancher_+ poutre_*). If the 3rd item is "Plateage" I can get the desired order (*_Platelage_circulation_* > *_Platelage_poutre CEP_* > *_Platelage_support de banche_*) with a simple (acad_strlsort) or (vl-sort ListType4 '>). Addition that i didnt't put in my code...

0 Likes
Message 8 of 8

pbejse
Mentor
Mentor

@roland.ifrene3T43E wrote:

Yes the InitialList is just an exemple of what the list could be. The InitialList is a list of layers that look like this (ACE-DQE_LevelVariable_TypeVariable_SlabVariable_ThicknessVariable_HeightVariable_SupportVariable_HatchType) Those variables are filled in a modeless form.

 

I put an additionnal condition for the 3rd Item "Plancher" because the ordre that i want to get from it is (*_Plancher_CEP_* > *_Plancher_prédalles_* > *_Plancher_alvéolaire_* > *_Plancher_+ voile_* > *_Plancher_+ poutre_*).


Very Interesting 🙂

I guess we can make a generic code  in case there's a need to add more option for nested sorting  other than "Plancher"

 

0 Likes