• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    Visual LISP, AutoLISP and General Customization

    Reply
    *Expert Elite*
    Kent1Cooper
    Posts: 4,167
    Registered: ‎09-13-2004

    Re: Assign variable if item is a member of a list?

    01-19-2013 05:51 AM in reply to: mid-awe

    Without loading it up and trying it, I suspect what you need to do is to change this section:

    ....

         (cond
           ((foreach PLANT PALM (member PLANT PALM)) "PALM")
           ((foreach PLANT TREE (member PLANT TREE)) "TREE")
           ((foreach PLANT SHRUB (member PLANT SHRUB)) "SHRUB")
         )

    ....

    to just this:

    ....

         (cond
           ((member PLANT PALM) "PALM")
           ((member PLANT TREE) "TREE")
           ((member PLANT SHRUB) "SHRUB")
         )

    ....

    Kent Cooper
    Please use plain text.
    *Expert Elite*
    Posts: 2,136
    Registered: ‎11-24-2009

    Re: Assign variable if item is a member of a list?

    01-19-2013 06:24 AM in reply to: mid-awe

    So you basically want to  process every item on the list if and only if the block associated with the list exists on the drawing session

     

    Here's a demo: You may need to add your list before you try this code :

     

    (Defun c:demo ( / MasterList Palm Tree shrub dictname)    
    (vl-load-com)
    ;;;	This section will create a master list filtering out items  	;;;
    ;;;	if the block does not exist in the drawing session		;;;
    (if  (setq MasterList (mapcar 'cadr
    	(vl-remove-if-not
    	  	'(lambda (i)(tblsearch "block" (car i)))
    	        '(("Palms_DYN" PALM) ("Tree_DYN"  TREE)("SHRUB_DYN" SHRUB)))))
    ;;;	This section will iterate thru the remaining list variables	;;;
      
      	(foreach lst MasterList
              	(setq dictname (vl-symbol-name lst))
              	(foreach key (eval lst)
                      	(princ (strcat "\n" key ": " (rtos (dict-get dictname key) 2 0)))
                      )
              )
      (princ "\nBlocks Not found")
      )
      (princ)
      )

     

    HTH

    Please use plain text.
    Mentor
    Posts: 244
    Registered: ‎12-31-2009

    Re: Assign variable if item is a member of a list?

    01-21-2013 03:19 AM in reply to: Kent1Cooper

    Kent1Cooper wrote:

     

    ...

     

    But you're not correct about the second problem, though I grant that it might be better not to use that word as an argument, just to avoid any possible confusion.  "List" as used there is not a variable in the usual sense [there is no (setq List ...) happening], but rather a place-holder argument inside the (foreach) function.  Yes, the AutoLISP Reference describes it as assigning each item to a variable named for the 'name' argument, but it's not in the same way as (setq) does it.  Think of it as being like a localized variable in a (defun)'d routine or command, in that it has no meaning, nor any effect on anything else, outside the (foreach) function in which it is used.  It does work.  If I do this:

     

    (setq ListA '(1 2 3) ListB '(4 5 6) ListC '(7 8 9))

     

    and then run that routine, removing the [...etc....] part from the top line, and using [for example] 6 for YourItem, it puts into VariableForUseLater the correct list:

     

    !VariableForUseLater

    (4 5 6)

     

    And similarly finds the correct list with other YourItem values.  And it has no effect on the (list) function, which continues to function normally afterwards.


    I don't know the compiler internals, but running the interpreter in the VLIDE Console window I seem to be getting
    different results:

     

    $ (setq lista '(1 2 3) listb '(4 5 6) listc '(7 8 9))
    (7 8 9)
    _$ (setq MasterList (list ListA ListB ListC))
    ((1 2 3) (4 5 6) (7 8 9))
    _$ (foreach List MasterList

      (if (member YourItem List)

        (setq VariableForUseLater List)

      ); if

    ); foreach
    ; User warning: assignment to protected symbol: LIST <- (1 2 3)
    _1_$

     

    ...............
    LOG Trace stack
    ...............
    <1> :smileytongue:ROTECT-ASSIGN LIST := (1 2 3)
    [2] (FOREACH ...)
    [3] (#<USUBR @2c4512d0 -top->)
    <4> :USER-INPUT (foreach List MasterList
        (if (member YourItem List)
            (setq VariableForUseLater List)))
    <5> :CALLBACK-ENTRY
    [6] (C:VLIDE)
    <7> :CALLBACK-ENTRY

     

     

    - On the other hand, the assignment disappears outside the FOREACH call, so this would only produce an error if I tried to call the LIST function inside the FOREACH loop:

     

    _$ (foreach list '((1)(2)) (print (list list)))
    ; User warning: assignment to protected symbol: LIST <- (1)
    _1_$
    ; continue after break loop
    ; error: bad function: (1)

    _1$ list
    (1)
    _1$
    ; reset after error
    _$ list
    #<SUBR @28058e08 LIST>

    --

    Please use plain text.
    *Expert Elite*
    Kent1Cooper
    Posts: 4,167
    Registered: ‎09-13-2004

    Re: Assign variable if item is a member of a list?

    01-21-2013 05:30 AM in reply to: martti.halminen

    martti.halminen wrote:
    .... 

    - On the other hand, the assignment disappears outside the FOREACH call, so this would only produce an error if I tried to call the LIST function inside the FOREACH loop:

    ....


    It did occur to me later that there could be a problem in that circumstance, so your suggestion not to use that as an argument name is certainly worthwhile.

    Kent Cooper
    Please use plain text.
    Distinguished Contributor
    Posts: 831
    Registered: ‎12-08-2004

    Re: Assign variable if item is a member of a list?

    01-21-2013 07:08 AM in reply to: pbejse

    Thank you all for your help. Maybe this should not have been so difficult but it was. I really appreciate everyones help and now this is working exactly as I need it to. A great solution here saving me hundreds of lines of code. Again, thank you all. :smileyvery-happy:

    Please use plain text.
    Distinguished Contributor
    Posts: 831
    Registered: ‎12-08-2004

    Re: Assign variable if item is a member of a list?

    01-21-2013 11:03 AM in reply to: pbejse

    I have one more quick question.

     

    I tried to use :

     

    (foreach PLANT (vl-sort PLANTS '(lambda (x y) (< (car x) (car y))))
      (setq CATEGORY (vl-symbol-name PLANT))
      (foreach PLANTNAME (eval PLANT)
        (if	(>= (dict-get CATEGORY PLANTNAME) 1)
          (princ (strcat "\n\t "
    		     PLANTNAME
    		     " : "
    		     (rtos (dict-get CATEGORY PLANTNAME) 2 0)
    	     )
          )
        )
        (setq total (+ total (dict-get CATEGORY PLANTNAME)))
      )
    )

     To get the list alphabetized, but it didn't work. How can I do it correctly?

     

    Thank you.

    Please use plain text.
    *Expert Elite*
    Posts: 2,136
    Registered: ‎11-24-2009

    Re: Assign variable if item is a member of a list?

    01-21-2013 06:58 PM in reply to: mid-awe

    mid-awe wrote:

    I have one more quick question.

     

     To get the list alphabetized, but it didn't work. How can I do it correctly?

     

    Thank you.


    Since  the plant lists are hard-coded, you can sort the lists PALM/TREE/SHRUBS then paste the sorted list in your code:

     

    (acad_strlsort palm)

    ("Bismark" "Blue Fan" "Date" "Fan" "Pindo" "Pineapple" "Ponytail" "Pygmy" "Queen" "Sabal" "Sago" "Windmill")

    (acad_strlsort shrub)

    (acad_strlsort tree)

     

    That way you dont have to sort the list everytime you use your routine

     

    HTH

     

    Cheers

     

    Please use plain text.
    Distinguished Contributor
    Posts: 831
    Registered: ‎12-08-2004

    Re: Assign variable if item is a member of a list?

    01-22-2013 02:31 PM in reply to: pbejse

    Thank you. I had a crazy idea about haveing the entire list sorted, but then I realized it makes little sense because they are categorized :smileylol:

    Please use plain text.