Author Topic: your loop of choice  (Read 1915 times)

0 Members and 1 Guest are viewing this topic.

A_LOTA_NOTA

  • Bull Frog
  • Posts: 202
your loop of choice
« on: November 29, 2010, 03:53:38 PM »
I typically use a while loop with a counter when cycling through a selection set. I'm sure like most things this can be done a number of ways. So I was just curious to see how everyone else does it.

Code: [Select]
 (setq ssmax (sslength ss))
  (setq count 0)
  (while (< count ssmax)
    (setq en (ssname ss count) ed (entget en ))
   )
« Last Edit: November 29, 2010, 04:01:30 PM by A_LOTA_NOTA »

Lee Mac

  • Seagull
  • Posts: 12390
  • London, England
Re: your loop of choice
« Reply #1 on: November 29, 2010, 03:58:32 PM »
Usually, something like:

Code: [Select]
(setq i -1)
(while (setq e (ssname ss (setq i (1+ i))))
 ...
)

Because it seems to be the fastest option uncompiled  :-)

kpblc

  • Bull Frog
  • Posts: 357
Re: your loop of choice
« Reply #2 on: November 29, 2010, 04:12:03 PM »
Another one:
Code: [Select]
(vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget))))And one more:
Code: [Select]
(setq selset (ssget))

((lambda (/ tab item)
   (repeat (setq tab  nil
                 item (sslength selset)
                 ) ;_ end setq
     (setq tab (cons (ssname selset (setq item (1- item))) tab))
     ) ;_ end of repeat
   ) ;_ end of lambda
 )
Sorry for my English.

gile

  • Water Moccasin
  • Posts: 2261
  • Marseille, France
Re: your loop of choice
« Reply #3 on: November 29, 2010, 04:12:46 PM »
Same as Lee or:

Code: [Select]
(repeat (setq n (sslength ss))
  (setq e (sname ss (setq n (1- n))))
  ...
)

depends my humor...

More, if I'm going the ActiveX route:
Code: [Select]
(vlax-for o (setq ss (vla-get-ActiveSelectionSet (vla-get-ActiveDocument (vlax-getacad-object))))
  ...
)
(vla-delete ss)
Speaking English as a French Frog

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9483
Re: your loop of choice
« Reply #4 on: November 29, 2010, 04:16:13 PM »
Lee,
mapcar-name
mapcar-lambda
can be fast as well; especially when put up against some "while-setq" situations.


I use them all but i start with a simple recursive process first (a lot of times its easier to think thru but...).
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

Lee Mac

  • Seagull
  • Posts: 12390
  • London, England
Re: your loop of choice
« Reply #5 on: November 29, 2010, 04:17:56 PM »
mapcar-name
mapcar-lambda
can be fast as well; especially when put up against some "while-setq" situations.

I do agree for most list operations, but in this case you lose a lot of speed with the ssnamex call...  :|

A_LOTA_NOTA

  • Bull Frog
  • Posts: 202
Re: your loop of choice
« Reply #6 on: November 29, 2010, 04:37:11 PM »
I was thinking of using "repeat" and that’s lead to posting this question. I have seen some nice code posted with mapcar and lambda. Both I would like to use sometime but don’t know much about them.

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9483
Re: your loop of choice
« Reply #7 on: November 29, 2010, 04:38:32 PM »
@Lee
Sure; I'll have to take your word on that (I dont even remember what ssnamex does to be honest).

I did find this one by me in my ss-lib and one by Vladimir which i thought were very similar. the only difference i saw was that he counted down and i counted up *lol*. I found a bunch of others some with names (Giles, CAB, etc) but these two were the most similar--and i laughed a little-.

Code: [Select]
(defun sel2lst ( sel / l len )
  ;; By: Vladimir Nesterovsky
  (if (= 'PICKSET (type sel))
   (repeat (setq len (sslength sel))
    (setq len (1- len) l (cons (ssname sel len) l)))))
;;or another alias for that
(setq sstol sel2lst)

Code: [Select]
(defun sset2-list (ss / lst cntr)
    ;; By: John K
    (setq cntr 0)
    (if (eq (type ss) 'PICKSET)
      (repeat (sslength ss)
              (setq lst
                    (append lst (list (list (ssname ss cntr)))))
              (setq cntr (1+ cntr)))
      '*ERROR* )
    lst )


@A_LOTA_NOTA
what do you mean you dont know about them? what dont you know? ask away people are here to help.
TheSwamp.org (serving the CAD community since 2003)

Donate to TheSwamp.org

T.Willey

  • Needs a day job
  • Posts: 5238
Re: your loop of choice
« Reply #8 on: November 29, 2010, 04:42:59 PM »
I used to use ' while ' with ' ssdel '.
Code: [Select]
(while (setq Ent (ssname ss 0))
    .......
    (ssdel Ent)
)

Mostly now I use the way Lee shows, that I picked up from Alan ( CAB ).
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

cmwade77

  • Swamp Rat
  • Posts: 1210
Re: your loop of choice
« Reply #9 on: November 29, 2010, 04:45:47 PM »
Lately my choice has been:
Code: [Select]
(while ss
       (setq item (ssname ss 0))
       ;Remainder of code here
       (ssdel (ssname ss 0))
)
Saves the extra variable of a counter, of course this only works if you do not want to reuse the selection set in another loop.

Lee Mac

  • Seagull
  • Posts: 12390
  • London, England
Re: your loop of choice
« Reply #10 on: November 29, 2010, 04:57:02 PM »
Not conclusive, but quick speed test:

Code: [Select]
(defun _while ( ss / l i )
  (setq i (sslength ss))

  (while (<= 0 (setq i (1- i)))
    (setq l (cons (ssname ss i) l))
  )
)


(defun _while2 ( ss / l i e )
  (setq i -1)

  (while (setq e (ssname ss (setq i (1+ i))))
    (setq l (cons e l))
  )
)


(defun _mapcar ( ss )
  (vl-remove-if (function listp)
    (mapcar (function cadr) (ssnamex ss))
  )
)


(defun _repeat ( ss / i l )
  (repeat (setq i (sslength ss))
    (setq l (cons (ssname ss (setq i (1- i))) l))
  )
)

Uncompiled:

Code: [Select]
SSLength: 5000 Entities
Elapsed milliseconds / relative speed for 256 iteration(s):

    (_WHILE2 SS).....1529 / 4.26 <fastest>
    (_WHILE SS)......1763 / 3.70
    (_REPEAT SS).....2074 / 3.14
    (_MAPCAR SS).....6521 / 1.00 <slowest>

Compiled:

Code: [Select]
SSLength: 5000 Entities
Elapsed milliseconds / relative speed for 1024 iteration(s):

    (_REPEAT SS)......1825 / 15.44 <fastest>
    (_WHILE SS).......1841 / 15.30
    (_WHILE2 SS)......1888 / 14.92
    (_MAPCAR SS).....28174 / 1.00 <slowest>
« Last Edit: November 29, 2010, 05:03:27 PM by Lee Mac »

A_LOTA_NOTA

  • Bull Frog
  • Posts: 202
Re: your loop of choice
« Reply #11 on: November 29, 2010, 05:20:47 PM »
@A_LOTA_NOTA
what do you mean you dont know about them? what dont you know? ask away people are here to help.

Thanks for the offer. After searching and finding the following threads I feel I have a better understanding.

http://www.theswamp.org/index.php?topic=340.0

http://www.theswamp.org/index.php?topic=2953.msg37000#msg37000+


dgorsman

  • Water Moccasin
  • Posts: 2422
Re: your loop of choice
« Reply #12 on: November 29, 2010, 05:38:25 PM »
Since most of my looping involves lists, I normally count backwards.  This lets me put the (length...) function before the loop so it only gets called once rather than every loop (list size rarely changes) and I compare the index to a constant (typically -1) in the test.  It also has the benefit of (cons...) calls internal to the loop keeping any resultant lists in the same order as the original without figuring where the (reverse...) call needs to be.

Recently I've had cases with *massive* lists which required iterating over the rest of the list to find matches.  In these cases I work with a (while main_list (setq cur_obj (car main_list)) ... (setq main_list (cdr main_list))) format.  The gradual reduction in list size improves speed but I consider it too complex for minor list management.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

ronjonp

  • Needs a day job
  • Posts: 7147
Re: your loop of choice
« Reply #13 on: November 29, 2010, 06:20:49 PM »
I use Lee's "While2" example.

Windows 10 x64 - AutoCAD /C3D 2020

Custom Build PC

fixo

  • Guest
Re: your loop of choice
« Reply #14 on: November 29, 2010, 06:27:15 PM »
I used to use ' while ' with ' ssdel '.
Code: [Select]
(while (setq Ent (ssname ss 0))
    .......
    (ssdel Ent)
)

Mostly now I use the way Lee shows, that I picked up from Alan ( CAB ).
I use the same way coz I have learned from you many moons ago :)
Regards
Oleg