- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Dear master lispers,
I need help, I can't find my mistake and it's driving me crazy
As part of a larger routine I need a routine that can tell me if two supplied lists are the same. the supplied lists can consist of strings/integers/reals or other lists (also definitely dotted pair lists)
The routine needs a flag because sometimes I just need to check if both lists have the same members (if even in multiple occurences) and other times I will need to check very precisely that both lists have the same members in the same order
I wrote the below routine. It sorts on flag, if the flag is given. It does a member check for one list against the other and vice versa, and will check the resulting list to see if there is a nil value in there, the routine will output nil or T accordingly. This has been tested and seems to work fine (it could be more efficient by not relying so heavily on the member function, but that would be an issue for later)
If the flag is not set, the comparison has to be precise, the position of the members need to correspond, each member needs to have a corresponding member in the corresponding position in the other list. In case that member is a list, its content also needs to match.
I decided to split the checks in different checks figuring that if any check is failed I can set the output to nil and move on with my life ^^
(defun CompareList ( l1 l2 flag / r cnt)
; take two lists
; get flag
; check if each list has the same members as the other
; if flag is not nil, list order & duplicity is not followed
; return T if lists are the same, return nil if lists are not the same
(if flag
(progn
(foreach m l1
(setq r (cons (member m l2) r))
)
(foreach m l2
(setq r (cons (member m l1) r))
)
(if
(member nil r)
(setq r nil)
(setq r T)
)
) ; do this if flag is not nil
(progn
(if
(= (length l1) (length l2))
(progn
(setq cnt 0
r T)
(while
(and (< cnt (length l1)) r)
(cond
((/= (type (nth cnt l1)) (type (nth cnt l2))) (setq r nil)) ; check if member type is the same
((= (type (nth cnt l1)) "LIST") (if (not (CompareList (nth cnt l1) (nth cnt l2) nil))(progn (setq r nil)))) ; if it is a list, repeat CompareList
((/= (type (nth cnt l1)) "LIST") (if (/= (nth cnt l1) (nth cnt l2)) (progn (setq r nil)))) ; if not list, check if the same
)
(setq cnt (1+ cnt))
)
) ; if the length of the lists does match -> check others
(progn
(setq r nil)
) ; if the length of the lists does not match -> nil
)
)
) ; check if flag is set
r
) ; end of Comparelist
(I'm using type checks instead of ltype because I got another error with ltype)
When I test the routine with the below code. I get the weird behaviour that when I do (CompareList att1 att1 nil) the routine correctly gives me T
But when I compare att1 and att2, though they both are construed in the same way, the routine incorrectly gives me nil.
(defun c:aaaaaa ( / att1 att2 att3)
(setq att1 (cons (cons 0 "a") att1))
(setq att1 (cons (cons 1 "b") att1))
(setq att2 (cons (cons 0 "a") att2))
(setq att2 (cons (cons 1 "b") att2))
(setq att3 (cons (cons 0 "a") att3))
(setq att3 (cons (cons 2 "c") att3))
(CompareList att1 att2 nil)
)
I can't figure it out what I'm missing. I'm hoping one of you might find the error in my code.
Thank you for your time.
Solved! Go to Solution.