drafter_joe Posted January 13, 2017 Share Posted January 13, 2017 Hi All! I have done some searching for information on this, but nothing very close to what I'm looking for. If you have a list of an unknown number of elements, how would someone go about assigning a different variable to each element in that list? Say for example you want the variables to be p1, p2, p3...p(# of total elements of the list). Is there a way to increment p# and assign it to the next element in the list? Thanks for the help in advanced! Drafter_Joe Quote Link to comment Share on other sites More sharing options...
David Bethel Posted January 13, 2017 Share Posted January 13, 2017 (edited) It is doable but has a lot of draw backs : [b][color=BLACK]([/color][/b]setq i 0[b][color=BLACK])[/color][/b] [b][color=BLACK]([/color][/b]setq lst '[b][color=FUCHSIA]([/color][/b][color=#2f4f4f]"a"[/color] [color=#2f4f4f]"b"[/color] [color=#2f4f4f]"d"[/color] [color=#2f4f4f]"e"[/color][b][color=FUCHSIA])[/color][/b][b][color=BLACK])[/color][/b] [b][color=BLACK]([/color][/b]foreach v lst [b][color=FUCHSIA]([/color][/b]set [b][color=NAVY]([/color][/b]read [b][color=MAROON]([/color][/b]strcat [color=#2f4f4f]"P"[/color] [b][color=GREEN]([/color][/b]itoa i[b][color=GREEN])[/color][/b][b][color=MAROON])[/color][/b][b][color=NAVY])[/color][/b] v[b][color=FUCHSIA])[/color][/b] [b][color=FUCHSIA]([/color][/b]setq i [b][color=NAVY]([/color][/b]1+ i[b][color=NAVY])[/color][/b][b][color=FUCHSIA])[/color][/b][b][color=BLACK])[/color][/b] It is almost impossible to localize these variables For retrieval of the data is also difficult : (eval (read (strcat "P" (itoa i)))) Differing data types in the list can cause havoc For starters HTH -David Edited January 13, 2017 by David Bethel Quote Link to comment Share on other sites More sharing options...
drafter_joe Posted January 13, 2017 Author Share Posted January 13, 2017 Thanks David! I'll give your code a try. The data types used are coordinates of a rectangular polyline with chamfers. I'll report back what happens. Joe Quote Link to comment Share on other sites More sharing options...
drafter_joe Posted January 13, 2017 Author Share Posted January 13, 2017 I tried the code, just slightly different, (setq z 0) (foreach v coords (set (read (strcat "P" (itoa z)) v) (setq z (1+ z))) ) This is what is returned: ; error: too many arguments _$ I should've mentioned the data in the list are point coordinates in the 1st post. I am guessing that fact makes this more difficult to do. Thank you for trying, David, I appreciate it! Joe Quote Link to comment Share on other sites More sharing options...
Grrr Posted January 13, 2017 Share Posted January 13, 2017 Based on this part from the tutorial on afralisp: This works, but is an extremely slow way of processing the data as each variable requires a program statement. A much more efficient way is to use the MAPCAR technique. (mapcar 'set '(a b c d) arglist) You could do this: (defun test ( / args n vals a b c d e f ) (setq args '(a b c d e f)) (setq n 0) (repeat (length args) (setq vals (cons n vals)) (setq n (1+ n)) ) (mapcar 'set args (reverse vals)) (list a b c d e f) ) _$ (test) (0 1 2 3 4 5) _$ EDIT: BTW consider this: (defun test ( / coords i p1 p2 p3 p4 p5 p6 p7 p8 p9) (setq coords '("First" "Second" "Third" "Fourth" "Fifth" "Sixth" "Seventh" "Eighth?" "Ninth?")) (repeat (setq i (length coords)) (set (read (strcat "P" (itoa i))) (nth (setq i (1- i)) coords)) ) (foreach x (list p1 p2 p3 p4 p5 p6 p7 p8 p9) (print x) ) (princ) ) _$ (test) "First" "Second" "Third" "Fourth" "Fifth" "Sixth" "Seventh" "Eighth?" "Ninth?" _$ But I agree with D.Bethel that its almost impossible to localise these variables. Quote Link to comment Share on other sites More sharing options...
Tharwat Posted January 13, 2017 Share Posted January 13, 2017 Have a close look at the following: (set (read (strcat "P" (itoa z))) v) Quote Link to comment Share on other sites More sharing options...
drafter_joe Posted January 13, 2017 Author Share Posted January 13, 2017 Thanks for taking a look at my question Grrr & Thwart! I appreciate your input. But with my list consisting of coordinates of a pline rectangle, in order to use the "read" function, it appears to me that I will have to deconstruct the coordinate list, turn each atom of each element into strings, then reconstruct the elements with those strings and then complete the list with the new elements. And from this I would be thinking another "foreach" function would allow me to handle the deconstruction and reconstruction of the coordinate list? I think I have seen that done before. Or, turn each element into strings before the original list is constructed? Am I thinking correctly? Thanks again, guys! Quote Link to comment Share on other sites More sharing options...
David Bethel Posted January 13, 2017 Share Posted January 13, 2017 I tried the code, just slightly different, I should've mentioned the data in the list are point coordinates in the 1st post. I am guessing that fact makes this more difficult to do. Thank you for trying, David, I appreciate it! Joe Try the revised code now. It was missing 1 parenthesis ( I should have tested the final snippet ) Quote Link to comment Share on other sites More sharing options...
Tharwat Posted January 13, 2017 Share Posted January 13, 2017 Try it this way: (defun SetvariableToEachCoordinate (s / e i l) (if (and (eq (type s) 'ENAME) (= (cdr (assoc 0 (setq e (entget s)))) "LWPOLYLINE") (setq i 0) ) (mapcar '(lambda (x) (set (read (strcat "P" (itoa (setq i (1+ i))))) x) (setq l (cons (read (strcat "P" (itoa i))) l)) ) (mapcar 'cdr (vl-remove-if-not '(lambda (q) (= (car q) 10)) e)) ) ) (reverse l) ) (SetvariableToEachCoordinate (car (entsel "\nSelect polyline :"))) Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted January 13, 2017 Share Posted January 13, 2017 I would strongly suggest retaining & manipulating the data in a list format - after all, LISP is designed for LISt Processing. As David has already outlined above, using individual variables for each item element can lead to several issues. Quote Link to comment Share on other sites More sharing options...
drafter_joe Posted January 13, 2017 Author Share Posted January 13, 2017 Try it this way: Code: (defun SetvariableToEachCoordinate (s / e i l) (if (and (eq (type s) 'ENAME) (= (cdr (assoc 0 (setq e (entget s)))) "LWPOLYLINE") (setq i 0) ) (mapcar '(lambda (x) (set (read (strcat "P" (itoa (setq i (1+ i))))) x) (setq l (cons (read (strcat "P" (itoa i))) l)) ) (mapcar 'cdr (vl-remove-if-not '(lambda (q) (= (car q) 10)) e)) ) ) (reverse l) ) Code: (SetvariableToEachCoordinate (car (entsel "\nSelect polyline :"))) This works excellently! Thank you Tharwat! I appreciate all the help I have received on my question! Well done guys!! Quote Link to comment Share on other sites More sharing options...
Tharwat Posted January 13, 2017 Share Posted January 13, 2017 This works excellently! Thank you Tharwat! I appreciate all the help I have received on my question! Well done guys!! You're welcome. Quote Link to comment Share on other sites More sharing options...
Grrr Posted January 13, 2017 Share Posted January 13, 2017 I would strongly suggest retaining & manipulating the data in a list format - after all, LISP is designed for LISt Processing. As David has already outlined above, using individual variables for each item element can lead to several issues. 1+ BTW if I wanted to obtain myself any point from pline's vertices I would use an assoc list: (defun PlineVertices->AssocLst ( Pline / i ) (if (and (eq 'ENAME (type Pline)) (eq "LWPOLYLINE" (cdr (assoc 0 (entget Pline)))) (setq i 0) ) (apply 'append (mapcar '(lambda (x) (if (= 10 (car x)) (list (list (strcat "P" (itoa (setq i (1+ i)))) (cdr x))))) (entget Pline))) ) ) Example: _$ (setq Points (PlineVertices->AssocLst (car (entsel "\nPick a pline: ")))) (("P1" (525.741 276.008)) ("P2" (656.491 276.008)) ("P3" (656.491 199.127)) ("P4" (525.741 199.127)) ) _$ (setq Point3 (cadr (assoc "P3" Points))) (656.491 199.127) _$ Quote Link to comment Share on other sites More sharing options...
drafter_joe Posted January 13, 2017 Author Share Posted January 13, 2017 Lee MacI would strongly suggest retaining & manipulating the data in a list format - after all, LISP is designed for LISt Processing. As David has already outlined above, using individual variables for each item element can lead to several issues. Hi Lee! (Like I know you or something.) I see what you both mean. ( for giving David some backup!) My intention is to use the variables to automatically plot dimensions on a rectangle with chamfers. (I found one that does this to a rectangle) With your point in mind, I can't quite see how to recall just the right coordinates out of a list. Would you happen to have an example of how that would be done, as I'm sure it can be done that way, as a simpleton with LISP, it's just difficult for me see how. Thank you! Joe Quote Link to comment Share on other sites More sharing options...
drafter_joe Posted January 13, 2017 Author Share Posted January 13, 2017 GrrrQuote Originally Posted by Lee Mac View Post I would strongly suggest retaining & manipulating the data in a list format - after all, LISP is designed for LISt Processing. As David has already outlined above, using individual variables for each item element can lead to several issues. 1+ BTW if I wanted to obtain myself any point from pline's vertices I would use an assoc list: Code: (defun PlineVertices->AssocLst ( Pline / i ) (if (and (eq 'ENAME (type Pline)) (eq "LWPOLYLINE" (cdr (assoc 0 (entget Pline)))) (setq i 0) ) (apply 'append (mapcar '(lambda (x) (if (= 10 (car x)) (list (list (strcat "P" (itoa (setq i (1+ i)))) (cdr x))))) (entget Pline))) ) ) This appears to be the answer to my question to Lee before I asked it? (Says the simpleton:D) Quote Link to comment Share on other sites More sharing options...
drafter_joe Posted January 13, 2017 Author Share Posted January 13, 2017 Code:(defun SetvariableToEachCoordinate (s / e i l) (if (and (eq (type s) 'ENAME) (= (cdr (assoc 0 (setq e (entget s)))) "LWPOLYLINE") (setq i 0) ) (mapcar '(lambda (x) (set (read (strcat "P" (itoa (setq i (1+ i))))) x) (setq l (cons (read (strcat "P" (itoa i))) l)) ) (mapcar 'cdr (vl-remove-if-not '(lambda (q) (= (car q) 10)) e)) ) ) (reverse l) ) TharwatQuote Originally Posted by drafter_joe View Post This works excellently! Thank you Tharwat! I appreciate all the help I have received on my question! Well done guys!! You're welcome. I have a follow up question for you, Tharwat. What if I already have the polyline as a selection set? How would this get incorporated into your code? Thank you! Quote Link to comment Share on other sites More sharing options...
Tharwat Posted January 13, 2017 Share Posted January 13, 2017 I have a follow up question for you, Tharwat. What if I already have the polyline as a selection set? How would this get incorporated into your code? Thank you! So you would be in need of iterating through the selection set and implement the function on the entity name. eg: (repeat (setq nos (sslength selectionSet)) (setq lst (cons (SetvariableToEachCoordinate (ssname selectionSet (setq nos (1- nos)))) lst)) ) So the variable 'lst' would be a list of your desired variables that returned by my function. Quote Link to comment Share on other sites More sharing options...
drafter_joe Posted January 13, 2017 Author Share Posted January 13, 2017 TharwatQuote Originally Posted by drafter_joe View Post I have a follow up question for you, Tharwat. What if I already have the polyline as a selection set? How would this get incorporated into your code? Thank you! So you would be in need of iterating through the selection set and implement the function on the entity name. eg: Code: (repeat (setq nos (sslength selectionSet)) (setq lst (cons (SetvariableToEachCoordinate (ssname selectionSet (setq nos (1- nos)))) lst)) ) So the variable 'lst' would be a list of your desired variables that returned by my function. Yes, I see now. Very nice Tharwat! Thank you again! Joe Quote Link to comment Share on other sites More sharing options...
Tharwat Posted January 13, 2017 Share Posted January 13, 2017 Yes, I see now. Very nice Tharwat! Thank you again! Joe Happy coding Joe. Quote Link to comment Share on other sites More sharing options...
drafter_joe Posted January 13, 2017 Author Share Posted January 13, 2017 Using the all the code that has been supplied, I will post my findings after the weekend. Grrr, Lee, David, GrrrQuote Originally Posted by Lee Mac View Post I would strongly suggest retaining & manipulating the data in a list format - after all, LISP is designed for LISt Processing. As David has already outlined above, using individual variables for each item element can lead to several issues. 1+ BTW if I wanted to obtain myself any point from pline's vertices I would use an assoc list: Code: (defun PlineVertices->AssocLst ( Pline / i ) (if (and (eq 'ENAME (type Pline)) (eq "LWPOLYLINE" (cdr (assoc 0 (entget Pline)))) (setq i 0) ) (apply 'append (mapcar '(lambda (x) (if (= 10 (car x)) (list (list (strcat "P" (itoa (setq i (1+ i)))) (cdr x))))) (entget Pline))) ) ) this is beginning to make sense. I will have to look at least a few more time to comprehend it completely. Thanks to all of you for all the help you've provided in just this afternoon alone! Once again, as it has been said a number of times already in a large number of posts here, what a great help you guys are to the rest of us not as learned as you!! Cheers! and Joe Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.