Reputation: 309
My task is to find if a given element is contained in a list (non-linear list). This is what I've written for now, but the return value from this function is a list, which I don't really understand why.
(setq E 4)
(defun IsMember (L)
(cond
((equal E L)
T
)
((atom L)
NIL
)
(T
(or (mapcar 'IsMember L))
)
)
)
(print (IsMember '(1 2 3 (((4) 5) 6))))
The returns value is: (NIL NIL NIL (((T) NIL) NIL))
But it should really output T
or NIL
if E
is not found in the given list.
Upvotes: 0
Views: 369
Reputation: 139381
Your code:
(defun is-member (l e)
(cond
((equal e l)
t)
((atom l)
nil)
(t
(some #'(lambda (a)
(if (equal t a) t nil))
(mapcar #'(lambda (b) (is-member b e)) l)))))
Get rid of IF
You test if something is T and then you return T. You can get rid of that.
(defun is-member (l e)
(cond
((equal e l)
t)
((atom l)
nil)
(t
(some #'(lambda (a)
(equal t a))
(mapcar #'(lambda (b) (is-member b e)) l)))))
Get rid of EQUAL
Since the list consists of T and NIL, EQUAL can be replaced, too
(defun is-member (l e)
(cond
((equal e l)
t)
((atom l)
nil)
(t
(some #'identity
(mapcar #'(lambda (b) (is-member b e)) l)))))
Get rid of MAPCAR
Since MAPCAR returns a list of T and NIL, we can remove that, too.
The result:
(defun is-member (list e)
(cond ((equal list e) t)
((atom list) nil)
(t (some (lambda (b) (is-member b e))
list))))
Get rid of COND condition/value pairs
Since COND is used like an OR, we can replace COND with OR. We don't need to have the condition/value pair anymore:
(defun is-member (list e)
(or (equal list e)
(and (consp list)
(some (lambda (b) (is-member b e))
list))))
Upvotes: 6
Reputation: 38924
Your solution can be rewritten more simply as:
(defun is-member (element tree)
(flet ((recurse (e) (is-member e tree)))
(or (equal element tree)
(and (consp tree)
(some #'recurse tree)))))
But you do not even need to use some
:
(defun is-member (element tree)
(or (equal element tree)
(and (consp tree)
(or (is-member element (car tree))
(is-member element (cdr tree))))))
Upvotes: 2
Reputation: 309
Thanks for help, managed to not use OR anymore
(defun IsMember (L E)
(cond
((equal E L)
T
)
((atom L)
NIL
)
(T
(some #'(lambda (A) (if (equal T A) T NIL)
(mapcar #'(lambda (B) (IsMember B E)) L))
)
)
)
Not sure if ethical enought but does the job...
Upvotes: 0