Jump to content

Assign a different variable to each item in a list


drafter_joe

Recommended Posts

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

Link to comment
Share on other sites

  • Replies 22
  • Created
  • Last Reply

Top Posters In This Topic

  • drafter_joe

    11

  • Tharwat

    5

  • Grrr

    3

  • David Bethel

    2

Top Posters In This Topic

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 by David Bethel
Link to comment
Share on other sites

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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!

Link to comment
Share on other sites

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 )

Link to comment
Share on other sites

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 :")))

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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! :thumbsup:

 

I appreciate all the help I have received on my question! Well done guys!! :beer:

Link to comment
Share on other sites

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)
_$ 

Link to comment
Share on other sites

Lee Mac

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.

 

Hi Lee! (Like I know you or something.:))

 

I see what you both mean. (:thumbsup: 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

Link to comment
Share on other sites

Grrr

Quote 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)

Link to comment
Share on other sites

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)

)

Tharwat

Quote 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!

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

Tharwat

Quote 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

Link to comment
Share on other sites

Using the all the code that has been supplied, I will post my findings after the weekend.

 

Grrr, Lee, David,

 

Grrr

Quote 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! :beer: and :celebrate:

 

Joe

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...