TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: mailmaverick on March 26, 2015, 03:20:50 PM

Title: ssget Multiple Layers stored in LIST
Post by: mailmaverick on March 26, 2015, 03:20:50 PM
I have a list variable containing multiple layer names (length of list is dynamic) as strings.

For example :

(setq layerlist (list "0" "Layer1" "Layer2" "Layer3" "ABCD" "DEFG" "HIJK"))

I want to make a selection set (ssget) of all entities which are in these above layers.

How to do that in ssget by using layerlist ?
Title: Re: ssget Multiple Layers stored in LIST
Post by: ChrisCarlson on March 26, 2015, 03:35:58 PM
Code - Auto/Visual Lisp: [Select]
  1.  
  2. (setq lst'("0""1""2""3"))
  3.         (defun _layersel ( lst)
  4.                 (apply 'append (subst nil (list nil) (mapcar 'list lst)))
  5.                 (foreach layer lst (ssadd (ssget "_A" (list (cons 8 layer))) ss))
  6.         )
  7.  

Perhaps?
Title: Re: ssget Multiple Layers stored in LIST
Post by: roy_043 on March 26, 2015, 04:15:04 PM
Two options:

Using OR:
Code - Auto/Visual Lisp: [Select]
  1.   "_X"
  2.   (append
  3.     '((-4 . "<OR"))
  4.     (mapcar '(lambda (lyr) (cons 8 lyr)) layerlist)
  5.     '((-4 . "OR>"))
  6.   )
  7. )

Without OR:
Code - Auto/Visual Lisp: [Select]
  1. (defun KGA_String_Join (strLst delim)
  2.   (if strLst
  3.     (apply
  4.       'strcat
  5.       (cons
  6.         (car strLst)
  7.         (mapcar '(lambda (a) (strcat delim a)) (cdr strLst))
  8.       )
  9.     )
  10.     ""
  11.   )
  12. )
  13.  
  14. (ssget "_X" (list (cons 8 (KGA_String_Join layerlist ","))))
Title: Re: ssget Multiple Layers stored in LIST
Post by: David Bethel on March 26, 2015, 05:23:13 PM
Maybe :

Code - Auto/Visual Lisp: [Select]
  1.   (setq layerlist (list "0" "Layer1" "Layer2" "Layer3" "ABCD" "DEFG" "HIJK"))
  2.  
  3.   (setq ll '((-4 . "OR>")))
  4.   (foreach l layerlist
  5.         (setq ll (cons (cons 8 l) ll)))
  6.   (setq ll (cons '(-4 . "<OR") ll))
  7.  
  8.   (setq ss (ssget "X" ll))
  9.  

-David
Title: Re: ssget Multiple Layers stored in LIST
Post by: BlackBox on March 26, 2015, 05:25:27 PM
... Or simply:

Code - Auto/Visual Lisp: [Select]
  1. (defun _strcat (layers delim)
  2.     delim
  3.     (apply
  4.       'strcat
  5.       (mapcar (function (lambda (x) (strcat x delim))) layers)
  6.     )
  7.   )
  8. )
  9.  



Code - Auto/Visual Lisp: [Select]
  1. (setq layerlist (list "0" "Layer1" "Layer2" "Layer3" "ABCD" "DEFG" "HIJK"))
  2.  
  3. (sssetfirst nil (ssget "_x" (list (cons 8 (_strcat layerlist  ",")))))
  4.  
Title: Re: ssget Multiple Layers stored in LIST
Post by: roy_043 on March 27, 2015, 04:53:56 AM
... Or simply:
I think your solution is (almost) the same as my 2nd suggestion.
Title: Re: ssget Multiple Layers stored in LIST
Post by: Lee Mac on March 27, 2015, 07:02:13 AM
Using OR:
Code - Auto/Visual Lisp: [Select]
  1.   "_X"
  2.   (append
  3.     '((-4 . "<OR"))
  4.     (mapcar '(lambda (lyr) (cons 8 lyr)) layerlist)
  5.     '((-4 . "OR>"))
  6.   )
  7. )

This is the route that I would take, as I recall that there may be a limit on the string length for ssget filter list items, and such a limit would obviously be reached earlier than any possible limit on the number of filter list items.
Title: Re: ssget Multiple Layers stored in LIST
Post by: ChrisCarlson on March 27, 2015, 08:54:04 AM
... Or simply:

Code - Auto/Visual Lisp: [Select]
  1. (defun _strcat (layers delim)
  2.     delim
  3.     (apply
  4.       'strcat
  5.       (mapcar (function (lambda (x) (strcat x delim))) layers)
  6.     )
  7.   )
  8. )
  9.  



Code - Auto/Visual Lisp: [Select]
  1. (setq layerlist (list "0" "Layer1" "Layer2" "Layer3" "ABCD" "DEFG" "HIJK"))
  2.  
  3. (sssetfirst nil (ssget "_x" (list (cons 8 (_strcat layerlist  ",")))))
  4.  

Wouldn't selecting items on frozen/locked layers cause an error when it comes time to do something with the selection set? Also what happens if you pass a null layer value?
Title: Re: ssget Multiple Layers stored in LIST
Post by: BlackBox on March 27, 2015, 09:10:00 AM
... Or simply:
I think your solution is (almost) the same as my 2nd suggestion.

Many ways to skin a cat; I posted it for the sole purpose that it is a slight adaptation to what had already been posted. :-)



Using OR:
Code - Auto/Visual Lisp: [Select]
  1.   "_X"
  2.   (append
  3.     '((-4 . "<OR"))
  4.     (mapcar '(lambda (lyr) (cons 8 lyr)) layerlist)
  5.     '((-4 . "OR>"))
  6.   )
  7. )

This is the route that I would take, as I recall that there may be a limit on the string length for ssget filter list items, and such a limit would obviously be reached earlier than any possible limit on the number of filter list items.

I don't particularly like the way the code 'looks'

This:
Code - Auto/Visual Lisp: [Select]
  1.   "_X"
  2.   '((-4 . "<OR")
  3.     (8 . "0")
  4.     (8 . "Layer1")
  5.     (8 . "Layer2")
  6.     (8 . "Layer3")
  7.     (8 . "ABCD")
  8.     (8 . "DEFG")
  9.     (8 . "HIJK")
  10.     (-4 . "OR>")
  11.   )
  12. )
  13.  


... Compared to this:
Code - Auto/Visual Lisp: [Select]
  1. (ssget "_x" (list (8 . "0,Layer1,Layer2,Layer3,ABCD,DEFG,HIJK")))
  2.  


... But... The speed difference is quite impressive - thanks for commenting, as it prompted me to take a second look.



Wouldn't selecting items on frozen/locked layers cause an error when it comes time to do something with the selection set?

That entirely depends on the logic you build into your code, frankly... Being that this is a would-be sub-function, I'd suggest that your main code handle the qualifying of the members of layerList being passed from the outset, rather than to expect the sub-function to account for user error, YMMV.



Also what happens if you pass a null layer value?

As the creator of the list argument being passed, you'd have intentionally passed nil or empty string... Or intentionally written code that allows for such a potentiality in the first place.



Cheers all.
Title: Re: ssget Multiple Layers stored in LIST
Post by: Lee Mac on March 27, 2015, 10:58:17 AM
Code - Auto/Visual Lisp: [Select]
  1. (setq lst'("0""1""2""3"))
  2.         (defun _layersel ( lst)
  3.                 (apply 'append (subst nil (list nil) (mapcar 'list lst)))
  4.                 (foreach layer lst (ssadd (ssget "_A" (list (cons 8 layer))) ss))
  5.         )

I think you are missing a setq expression here:
Code - Auto/Visual Lisp: [Select]
  1. (apply 'append (subst nil (list nil) (mapcar 'list lst)))

Else the line is redundant since you are not using the return of the apply expression.
Title: Re: ssget Multiple Layers stored in LIST
Post by: mailmaverick on March 27, 2015, 01:47:43 PM
Thanks to all forum gurus. I just wanted one solution but got multiple.

Thus, I mark this thread as 500% solved.  :-D :-D