Author Topic: nested "FOR NEXT"  (Read 6495 times)

0 Members and 1 Guest are viewing this topic.

Robert98

  • Guest
nested "FOR NEXT"
« on: October 26, 2010, 03:09:03 PM »
Hi dear members
I want make a nested "FOR NEXT" functions in autolisp , I see in autolisp reference that vlisp have a vlax-for , but I'm beginner and don't want use of vlisp objective properties and methods now ,so I used Allan Wise algorithm .
In addition I know that my example is very simple and may be there are very simple solutions , but my purpose is just practice on autolisp programming , if may be anybody read my codes and tell me my blunders .

thanks

codes :

Code: [Select]
(defun for ( initializer condition indexer body_code / )
  ;by Allan Wise in http://www.draftsperson.net/index.php?title=AutoLISP_Lesson_8_-_LOOPING
(eval initializer)
(while (eval condition)
(foreach n body_code (eval n))
(eval indexer))
);end defun for

;===============

(defun pred (/ A B)
   (if (/=  A B) T nil)
  );end of defun predictio

;===============

(defun REMOVE-IF-NOT (pred lst)        ; by Vladimir Nesterowsky
    (apply 'append
           (mapcar '(lambda (e)
                    (if (apply pred (list e)) (list e))) lst)))

;===============

  (defun C:MY_TEST (lis1
   lis2
   /
   x
   y)

;lis1 and lis2 are list and x , y any paeticular members of lists
   (setq lis1 '(10 12 14 15 13)
 lis2 '(74 1114 12 13 15 18)
   ) ;example lists
   (for
     '(setq x 0)
     '(<= x (length lis1))
     '(setq x (1+ x))
     '((setq A (nth x lis1)))


     (for
'(setq y 0)
'(<= y (length lis2))
'(setq y (1+ y))
'((setq B (nth Y lis2)))
(if (pred x y)
 T
 (progn
   (REMOVE-IF-NOT pred lis1)
   (REMOVE-IF-NOT pred lis2)
 ) ;end of progn
) ;end of if

     ) ;end for y

   ) ;end for x
   (princ lis1 "\n")
   (princ lis2)
   (princ)

  ) ;end of MY_TEST defun



please just in autolisp format .! :-(

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: nested "FOR NEXT"
« Reply #1 on: October 26, 2010, 03:43:32 PM »
Some quick remarks:
The for function requires 4 arguments and you supply 5.
The pred function requires no arguments and you supply 2.
Your command function C:MY_TEST requires 2 arguments. A command function normally doesn't have any arguments.

In general:
You're using chunks of quite sophisticated code without completely understanding what you are doing.
It would help if you explain what you want to accomplish.

<EDIT: typo>
« Last Edit: October 27, 2010, 05:57:41 AM by roy_043 »

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: nested "FOR NEXT"
« Reply #2 on: October 26, 2010, 04:13:50 PM »
1+

Before trying to use this 'for' routine learn how work built-in functions.
AutoLISP provides iterative functions as: repeat, while and functions to deal with items in lists: foreach, mapcar.

I know about 'for' statement in other languages and had never need to implement (or use) such routine in AutoLISP.
Speaking English as a French Frog

Lee Mac

  • Seagull
  • Posts: 12915
  • London, England
Re: nested "FOR NEXT"
« Reply #3 on: October 26, 2010, 04:18:32 PM »
1+

Before trying to use this 'for' routine learn how work built-in functions.
AutoLISP provides iterative functions as: repeat, while and functions to deal with items in lists: foreach, mapcar.

I know about 'for' statement in other languages and had never need to implement (or use) such routine in AutoLISP.

I definitely agree with this ^^

Being a high level language, AutoLISP provides many constructs that other languages don't provide - I've never had need to create control statements from other languages.

Lee

JohnK

  • Administrator
  • Seagull
  • Posts: 10648
Re: nested "FOR NEXT"
« Reply #4 on: October 26, 2010, 04:37:22 PM »
This sounds to me like a learning exercise guys (the OP gave a link to a lesson).

Robert98,
Take a quick look at this procedure and see if you can follow what it is doing.

Code: [Select]
(defun copy (x)
  (if (atom x)
    x
    (cons (copy (car x))
 (copy (cdr x))
    )
  )
)
;; Use like this:

(copy '(0 1 2 3 4 5 6 7 8 9))

Then take a look at this:
Code: [Select]
(defun map-car (process aList)
  (if (null aList)
    nil
    (cons (process (car aList))
 (map-car process (cdr aList))
    )
  )
)
;; Use like this:

(map-car (lambda (x) (1+ x)) '(0 1 2 3 4 5 6 7 8 9))


« Last Edit: October 26, 2010, 04:42:52 PM by Se7en »
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: nested "FOR NEXT"
« Reply #5 on: October 26, 2010, 04:43:55 PM »
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

JohnK

  • Administrator
  • Seagull
  • Posts: 10648
Re: nested "FOR NEXT"
« Reply #6 on: October 26, 2010, 05:11:15 PM »
wut cha thinking MP?
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: nested "FOR NEXT"
« Reply #7 on: October 26, 2010, 09:58:26 PM »
Robert98, what are you really trying to achieve? Based upon your use of the code harvested from the link you provided I must deduce you are in a little over your head, so let's step back and understand what it is you want to learn and/or achieve.

Without the benefit of the above it almost appears as if you are trying to construct an intersection function, that is, determine the list elements common to two lists (like set theory intersection).

If so AND you don't wish to use vlisp functions this unoptimized code might illustrate:

Code: [Select]
(defun venn_inters ( list1 list2 / result )

    (foreach element list1
        (if (member element list2)
            (setq result (cons element result))
        )            
    )
    
    (reverse result)
    
)

example:

Code: [Select]
(venn_inters
    '(10 12 14 15 13)
    '(74 1114 12 13 15 18)
)

returns (12 15 13)

As such, nested foreach loops are not required, but I may be misinterpreting what you want to achieve. Also note that they are many ways to return the intersection of two lists, this was simple one using foreach.

An aside, while the do and for code provided in the link in your first post may have some mild academic value, from a practical stand point, i.e. what is used in typical day to day programming, they have little value for the majority of programmers imo, certainly not n00bz (no offense) and accordingly suggest you use tutorials that are more interested in helping the student new to lisp establish a solid knowledge base, rather than illuminate the teacher's prowess.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

JohnK

  • Administrator
  • Seagull
  • Posts: 10648
Re: nested "FOR NEXT"
« Reply #8 on: October 27, 2010, 12:01:46 AM »
Yeah i was (must have been) way off. I was thinking/going a different route. Sorry.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Robert98

  • Guest
Re: nested "FOR NEXT"
« Reply #9 on: October 27, 2010, 09:07:40 AM »
Some quick remarks:
The for function requires 4 arguments and you supply 5.
The pred function requires no arguments and you supply 2.
Your command function C:MY_TEST requires 2 arguments. A command function normally doesn't have any arguments.

In general:
You're using chunks of quite sophisticated code without completely understanding what you are doing.
It would help if you explain what you want to accomplish.

<EDIT: typo>
HI ROY
These are very useful tips for me and  I'll use them , but about "completely understanding what you are doing" I said to you that :
I have read that some lisp codes can call itself like :
codes:
Code: [Select]
(defun fact (n)
   (if (<= n 0)
      1
      (* n (fact
      (- n 1))))

So I wanted test it by Allan Wise for functions, and now I believe that lisp has it's limitations and capabilities .
Thanks for your help

Robert98

  • Guest
Re: nested "FOR NEXT"
« Reply #10 on: October 27, 2010, 09:18:49 AM »
This sounds to me like a learning exercise guys (the OP gave a link to a lesson).

Robert98,
Take a quick look at this procedure and see if you can follow what it is doing.

Code: [Select]
(defun copy (x)
  (if (atom x)
    x
    (cons (copy (car x))
 (copy (cdr x))
    )
  )
)
;; Use like this:

(copy '(0 1 2 3 4 5 6 7 8 9))

Then take a look at this:
Code: [Select]
(defun map-car (process aList)
  (if (null aList)
    nil
    (cons (process (car aList))
 (map-car process (cdr aList))
    )
  )
)
;; Use like this:

(map-car (lambda (x) (1+ x)) '(0 1 2 3 4 5 6 7 8 9))
HI Se7en
First thanks for your answer
I read your codes and I still have not used it , but I think it works on a single list not two , so I wrote to you later .
thanks and have good times


HI Se7en
I worked with your functions , the map-car function add 1 to all members of a list , but copy function return me :
_$ (copy '(0 1 2 3 4 5 6 7 8 9))
(0 1 2 3 4 5 6 7 8 9)
_$

I don't understand relationship between car and cdr whit this function , please give me another example.
thanks for your help
 :|
« Last Edit: October 27, 2010, 01:20:12 PM by Robert98 »

Robert98

  • Guest
Re: nested "FOR NEXT"
« Reply #11 on: October 27, 2010, 09:27:07 AM »
I have read that some lisp codes can call itself like :
You are referring to recursive functions. I don't see recursive functions in your OP. We still don't know what it is you want to accomplish.

Hi Roy
At this example I want compare two list and remove unequal members. but it is just a sample application and may by other time I want compare two list for other pourpose such as save four digit numbers and remove reminder members and so on . I want learn If I have more thane one list that their length isn't equal , how I can work with them simultaneously .for example I make a pline on a topographic map that it's z value is zero (in 2D space) at the other hand I have large amounts topographic text elevations and many contour , now I want filter coordinates of text and put it in list (for ample A) and then make a list of pline nodes , now suppose I want compare two list and remove undesired element and Finlay make a new list so that z value of text corespound to a node replaced by node z value !
for example :
text string elevation is : 1245.32
correspond node to it string has coordinates : (1000.0 1000.0 0.0)
my desired node coordinates must be :  (1000.0 1000.0 1245.32)
I do not know that I could , get you my purpose with this topographic and pline example or no ?
please note that I don't have any project and topographic map now and I just want learn about:1- compare two or more lists to each other for a certain purpose 2- How I can handling two or more lists simultaneously that don't have equal members (perhaps equal) 3- for this aim , I must start with ....?
sorry for my bad English skill.
thanks for your attention
« Last Edit: October 27, 2010, 01:12:01 PM by Robert98 »

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: nested "FOR NEXT"
« Reply #12 on: October 27, 2010, 09:30:09 AM »
I have read that some lisp codes can call itself like :
You are referring to recursive functions. I don't see recursive functions in your OP. We still don't know what it is you want to accomplish.

JohnK

  • Administrator
  • Seagull
  • Posts: 10648
Re: nested "FOR NEXT"
« Reply #13 on: October 27, 2010, 09:51:19 AM »
*confused* Maybe i wasn't as far off as i thought.

I have a question Robert98.
Do you know another programming language--like C--and you are just trying to learn AutoLisp?



My original thoughts were based upon a feeling from the formatting of the code posted (it kinda reminded me of a class def) and a quick scan of that tut page (after reading it closer i think its just bad but i originality thought it was written for a C to AutoLisp conversion tut or something).
...meh, never mind me.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: nested "FOR NEXT"
« Reply #14 on: October 27, 2010, 10:49:00 AM »
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

JohnK

  • Administrator
  • Seagull
  • Posts: 10648
Re: nested "FOR NEXT"
« Reply #15 on: October 27, 2010, 11:13:13 AM »
Dont mind me. I thought i saw something that wasnt really there i guess. I didnt know what "FOR NEXT" was so i was going off a...ah whatever, im nuts.

I built a tail recursive FORNEXT function that i was going to lead the OP to but i was approaching this more from the academic side because i thought that...*ah* yes, i realize im crazy so im just going to shut up and go away now.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

Robert98

  • Guest
Re: nested "FOR NEXT"
« Reply #16 on: October 27, 2010, 01:06:40 PM »
I have read that some lisp codes can call itself like :
You are referring to recursive functions. I don't see recursive functions in your OP. We still don't know what it is you want to accomplish.

Hi Roy
At this example I want compare two list and remove unequal members. but it is just a sample apllication and may by other time I want compare two list for other pourpose such as save four digit numbers and remove reminder members and so on . I want learn If I have more thane one list that their length is'nt equal , how I can work with them simultanusly .for example I make a pline on a topographic map that it's z value is zero (in 2D space) at the other hand I have large amounts topographic text elevations and many contur , now I want filter cordinates of text and put it in list (for eample A) and then make a list of pline nodes (for eample B) , now supose I want compare two list and remove undisired element and finaly make a new list so that z value of text corespound to a node replaced by node z value !
for example :
text string elevation is : 1245.32
corespoun node to it string has coordinates : (1000.0 1000.0 0.0)
my desired node coordinates must be :  (1000.0 1000.0 1245.32)
I do not know that I could , get you my purpose with this topographic and pline example or no ?
please note that I don't have any project and topographics map now and I just want learn about:1- compare two or more lists to each other for a certain purpose 2- How I can handling two or more lists simultanusly that don't have equal members (perhaps equal) 3- for this aim , I must start with ....?
sorry for my bad english skill.
thanks for your attention

Robert98

  • Guest
Re: nested "FOR NEXT"
« Reply #17 on: October 27, 2010, 01:24:13 PM »
*confused* Maybe i wasn't as far off as i thought.

I have a question Robert98.
Do you know another programming language--like C--and you are just trying to learn AutoLisp?



My original thoughts were based upon a feeling from the formatting of the code posted (it kinda reminded me of a class def) and a quick scan of that tut page (after reading it closer i think its just bad but i originality thought it was written for a C to AutoLisp conversion tut or something).
...meh, never mind me.

Hi
I can write VB and C++ and C but not professional , at a normal level

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: nested "FOR NEXT"
« Reply #18 on: October 27, 2010, 01:54:45 PM »
Hi,

MP shows you a way to do what you want reply #7 unsin the foreach function

Here's another way using the vl-remove-if-not built-in function. It's not a Visual LISP function using the COM/activeX interop, it's an AutoLISP function which came with Visual LISP.
As Vladimir Nesterowsky's remove_if_not many others vl-* functions have been defined as defun by AutoLISP pionners (Vladimir Nesterowsky, Reini Urban, ...).
You'd rather use the built-in vl-* functions than their old defun equivalents (but some of these are really intersting to study while you're learnig AutoLISP).

Code: [Select]
(defun common (l1 l2)
  (vl-remove-if-not
    (function (lambda (x) (member x l2)))
    l1
  )
)

As you're talking about "lisp codes can call itself" (recursive processes which are a main pat of all LISP languages), here's another example using this method:

Code: [Select]
(defun common (l1 l2)
  (if l1
    (if (member (car l1) l2)
      (cons (car l1) (common (cdr l1) l2))
      (common (cdr l1) l2)
    )
  )
)

With these lists
Code: [Select]
(setq lis1 '(10 12 14 15 13)
      lis2 '(74 1114 12 13 15 18)
)

With both above 'common' routines, (common lis1 lis2) return (12 13 15)
« Last Edit: October 27, 2010, 01:57:55 PM by gile »
Speaking English as a French Frog

Robert98

  • Guest
Re: nested "FOR NEXT"
« Reply #19 on: October 27, 2010, 05:34:58 PM »
Hi,

MP shows you a way to do what you want reply #7 unsin the foreach function

Here's another way using the vl-remove-if-not built-in function. It's not a Visual LISP function using the COM/activeX entrap, it's an AutoLISP function which came with Visual LISP.
As Vladimir Nesterowsky's remove_if_not many others vl-* functions have been defined as defun by AutoLISP pioneers (Vladimir Nesterowsky, Reini Urban, ...).
You'd rather use the built-in vl-* functions than their old defun equivalents (but some of these are really intersting to study while you're learning AutoLISP).

Code: [Select]
(defun common (l1 l2)
  (vl-remove-if-not
    (function (lambda (x) (member x l2)))
    l1
  )
)

As you're talking about "lisp codes can call itself" (recursive processes which are a main pat of all LISP languages), here's another example using this method:

Code: [Select]
(defun common (l1 l2)
  (if l1
    (if (member (car l1) l2)
      (cons (car l1) (common (cdr l1) l2))
      (common (cdr l1) l2)
    )
  )
)

With these lists
Code: [Select]
(setq lis1 '(10 12 14 15 13)
      lis2 '(74 1114 12 13 15 18)
)

With both above 'common' routines, (common lis1 lis2) return (12 13 15)
Hi Gile
thanks for your cooperation
I'll worked with these codes tomorrow ! and now I have a question of you :

One of my friends give me a lot of tools from Reini Urban that start wit STD , I read many papers of them , but don't work with them , dose you know what these functions , I must install them before use or they loaded by other method such as ARX , I wrote one of them please tell me about them because most of them are short routines :



Code: [Select]
;;; safe NTH version with reverse order of arguments
;;; Throws an index out of range error.
;;; NTH throw just a bad argument type error
;;; (from LISP)
;;; (STD-ELT '(0 1) 0) = > 0
;;; (STD-ELT lst -1) = > ERROR
;;; (STD-ELT lst (length lst )) = > ERROR

(defun STD-ELT (lst i)
(if (< -1 i (length lst));fixed
(nth i lst)
(std-error (list "STD-ELT: "
(std-msg ; |MSG2|;"index out of range")
" -" i))))
;===================================================
;;; std-select in NTH expanded for multiple indices.(from xlisp-stat)
;;;   (std-select lst '(0 2 4)) or (std-select lst 0)
(defun STD-SELECT (lst i / x)
(cond
((numberp i) (std-elt lst i))
((consp i)
(while i ; looping over i is faster than mapping over lst
(setq x (cons (std-elt lst (car i)) x)
i (cdr i)))
(reverse x))))
please tell me about these since I think they are'nt need runing vl objects. :-)

another thanks for your erenity

JohnK

  • Administrator
  • Seagull
  • Posts: 10648
Re: nested "FOR NEXT"
« Reply #20 on: October 27, 2010, 09:37:40 PM »
The STL library Reini wrote would be like any other STL library in any other language except that you do not use it or portions of it like you do in other languages.

For example:
In C++ "#include <iostream>"  Includes the I/O stream header file(s). AutoLisp does not have a an "INCLUDE" statement. You would have to manually add code to locate and load the AutoLisp STL file (like the one you are using as an example) you wanted to include. It is much easier to use the AutoLisp STL as a learning tool and write your own.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

hermanm

  • Guest
Re: nested "FOR NEXT"
« Reply #21 on: October 27, 2010, 10:50:26 PM »
Quote
AutoLisp does not have a an "INCLUDE" statement

At one time, AutoLISP might have progressed to that point.
Please see attached file, which shipped with R12.
AFAIK, it is a fake (read "aspiration")  & really isn't implemented per doc.
IOW the file is loaded in toto, not just the designated functions.
If I am mistaken, please correct me.

Implementing a real AutoLISP "include" is on my "to do" list. :)
Choice of programming language TBD - though I am leaning towards F#..
Would be a suitable challenge for me...
BTW, Anyone (else) here still use ALLY?

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: nested "FOR NEXT"
« Reply #22 on: October 27, 2010, 11:07:13 PM »
This is similar to an include statement insomuch as one statement can load an entire library (or libraries) of supporting lisp source.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Robert98

  • Guest
Re: nested "FOR NEXT"
« Reply #23 on: October 28, 2010, 02:17:59 PM »
Quote
AutoLisp does not have a an "INCLUDE" statement

At one time, AutoLISP might have progressed to that point.
Please see attached file, which shipped with R12.
AFAIK, it is a fake (read "aspiration")  & really isn't implemented per doc.
IOW the file is loaded in toto, not just the designated functions.
If I am mistaken, please correct me.

Implementing a real AutoLISP "include" is on my "to do" list. :)
Choice of programming language TBD - though I am leaning towards F#..
Would be a suitable challenge for me...
BTW, Anyone (else) here still use ALLY?

Dear hermanm
Thanks for your tips and very nice attached file . I think that with this function any body can load his small functions such as c++ that , dear Roy told. I don't further about this file since I'm beginner in lisp and must other master friend , tell about it . I must test it and wait for results ....!
Bay

Robert98

  • Guest
Re: nested "FOR NEXT"
« Reply #24 on: October 28, 2010, 02:23:08 PM »
This is similar to an include statement insomuch as one statement can load an entire library (or libraries) of supporting lisp source.
Hi MP
I have a question about include.lsp :
At that file wrote that make a file with llb extension and I want know these llb file have lisp codes or other language codes ?
bay master

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: nested "FOR NEXT"
« Reply #25 on: October 31, 2010, 07:02:45 PM »
I'll add my 2 cents to the discussion.
Dealing with two lists is easy.
One way was described by MP but keep in mind that the member or vl-position functions
do not preform well with real numbers because of rounding.  Slight variations will cause
them to fail to find a match. Dealing with real numbers you need to use equal with a fuzz
or use the distance function when dealing with point lists.
Example:
Code: [Select]
_$ (equal '(585.039 339.407) '(585.039 339.407))
T
_$ (equal '(585.03901 339.407) '(585.039 339.407))
nil
_$ (equal '(585.03901 339.407) '(585.039 339.407) 0.0001)
T


There is another potential problem using foreachfunction. When the foreachfunction is
initialized the list is placed in another hidden variable or memory location and is not bound
to the original list. If you alter the list within the foreachconstruct the change will not
be evident to the foreachfunction.
Example:
Code: [Select]
(setq lst '(1 2 3 4 5))
(foreach itm lst
  (if (= itm 2)
    (setq lst (reverse (cdr (reverse lst))))
  )
  (print itm) (princ " - ")(princ lst)
)
(princ)

You see although lst was changed to 4 items the foreachdid 5 iteration's.

Comparing two lists of point lists you might want to use nested foreachfunctions.

Code: [Select]
(defun c:test (/ lst1 lst2 p1 p2 matchList)
  (setq lst1 '((546.541 279.55)  ; 2D point list
               (585.039 339.407)
               (540.008 394.517)
               (473.68 368.72)
               (477.717 297.667)
              )
  )

  (setq lst2 '((546.541 279.55 12.5)  ; 3D point list
               (585.039 339.407 15.6)
               (540.008 394.517 22.7)
              )
  )

  (defun 2d (pt)                        ; return a point list less the Z value
    (list (car pt) (cadr pt))
  )

  (foreach p1 lst1
    (foreach p2 lst2
      (if (equal (2d p1) (2d p2) 0.0001)
        (setq matchList (cons p2 matchList))
      )
    )
  )
  (print matchList)
  (princ)
)

You can see that lst2 is iterated each time an item in lst1 is processed.
With large lists it may be desirable to remove a point from lst2 when it is paired.
To accomplish this the use of a while function does the job. The while function
will not store the list value and therefore your change will shorten the processing.

Code: [Select]
(defun c:test (/ lst1 lst2 p1 p2 idx matchList tmplst)
  (setq lst1 '((546.541 279.55)  ; 2D point list
               (585.039 339.407)
               (540.008 394.517)
               (473.68 368.72)
               (477.717 297.667)
              )
  )

  (setq lst2 '((546.541 279.55 12.5)  ; 3D point list
               (585.039 339.407 15.6)
               (540.008 394.517 22.7)
              )
  )

  (defun 2d (pt)                        ; return a point list less the Z value
    (list (car pt) (cadr pt))
  )

  (foreach p1 lst1
    (setq tmplst lst2)
    (while (setq p2 (car tmplst))
      (setq tmplst (cdr tmplst))
      (if (equal (2d p1) (2d p2) 0.0001)
        (setq matchList (cons p2 matchList)
              lst2 (vl-remove p2 lst2))
      )
    )
  )
  (print matchList)
  (princ)
)

You can also use a pointer with the while loop.

Code: [Select]
(defun c:test (/ lst1 lst2 p1 p2 idx matchList)
  (setq lst1 '((546.541 279.55)  ; 2D point list
               (585.039 339.407)
               (540.008 394.517)
               (473.68 368.72)
               (477.717 297.667)
              )
  )

  (setq lst2 '((546.541 279.55 12.5)  ; 3D point list
               (585.039 339.407 15.6)
               (540.008 394.517 22.7)
              )
  )

  (defun 2d (pt)                        ; return a point list less the Z value
    (list (car pt) (cadr pt))
  )

  (foreach p1 lst1
    (setq idx (length lst2))
    (while (>= (setq idx (1- idx)) 0)
      (setq p2 (nth idx lst2))
      (if (equal (2d p1) (2d p2) 0.0001)
        (setq matchList (cons p2 matchList)
              lst2 (vl-remove p2 lst2))
      )
      (print lst2)
    )
  )
  (print matchList)
  (princ)
)

You may wonder why the vl-remove works with point data, real numbers.
That only works because p2 is an exact copy of the data found in lst2.

That's it. 8-)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Lee Mac

  • Seagull
  • Posts: 12915
  • London, England
Re: nested "FOR NEXT"
« Reply #26 on: October 31, 2010, 07:13:54 PM »
Nice explanation Alan, very informative  8-)

Just to add my little snippet to the mix, one could perhaps construct a 'member with fuzz', maybe something like:

Code: [Select]
(defun _member ( item alist fuzz )
  (vl-some (function (lambda ( _item ) (equal _item item fuzz))) alist)
)

Code: [Select]
_$ (_member 585.039 '(585.03901 339.407) 0.0001)
T

Then, using the code MP kindly provided:

Code: [Select]
(defun venn_inters ( list1 list2 / result )

    (foreach element list1
        (if (_member element list2 0.0001)
            (setq result (cons element result))
        )           
    )
   
    (reverse result)
)

Just a thought  :-)

Lee

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Re: nested "FOR NEXT"
« Reply #27 on: October 31, 2010, 09:55:38 PM »
Good solution Lee.  8-)

My post was for information as the op seemed to want that.


I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: nested "FOR NEXT"
« Reply #28 on: November 01, 2010, 06:13:58 AM »
Lee,

All the 'member' family functions (member, vl-member-if, vl-member-if-not) return a list (or nil).
IMO, your '_member'  routine which return a boolean (T or nil) should have been named 'IsMember' or something like this.

Anyway, the 'vl-member-if' built-in function allows the same behavior as 'member' with a fuzz factor:

Code: [Select]
(defun common (l1 l2 fuzz)
  (vl-remove-if-not
    (function
      (lambda (x)
(vl-member-if
  (function (lambda (y) (equal x y fuzz)))
  l2
)
      )
    )
    l1
  )
)

Code: [Select]
(defun common (l1 l2 fuzz)
  (if l1
    (if (vl-member-if (function (lambda (x) (equal (car l1) x fuzz))) l2)
      (cons (car l1) (common (cdr l1) l2 fuzz))
      (common (cdr l1) l2 fuzz)
    )
  )
)
Speaking English as a French Frog

Lee Mac

  • Seagull
  • Posts: 12915
  • London, England
Re: nested "FOR NEXT"
« Reply #29 on: November 01, 2010, 11:36:10 AM »
I agree - thanks Gile!  :-)

Can't believe I overlooked vl-member-if ...