Reputation: 31
I have implemented this function. It is supposed to check the input that we have given to it, and if it is found in the list, a "True" will be shown on the screen. However, it just works for the numbers and if I give it a character I receive an error.
(defun element (x lst)
(dolist (item lst)
(if (= item x) (return t))))
How can I modify it so that it can also look for any characters given to it? Thanks in advance.
Upvotes: 1
Views: 528
Reputation: 20269
Easy, use #'eq instead of #'=, thus the 3rd line becomes: (if (eq item x) ...
Alternatively, you could use the built-in #'intersection to check if any of the given items are in the list, thus: (if (not (eq (intersection lst '(x)) nil)))
Upvotes: 1
Reputation: 15269
As you discovered, the =
function only works with numbers.
If you try basing your function on find
instead, you'll likely find that its default use of the eql
function as its test provides the behavior you seek:
(defun element (needle haystack)
(not (null (find needle haystack))))
As alternates to find
, you should also study its siblings member
and position
. In your case, since you only want to distinguish between the item having been found or not, you should choose the function that does the least work. My guess is that position
loses here, and that member
and find
are equivalent; member
returns the list from which it extracted the car
, whereas find
returns the car
. In both functions, it's necessary to extract the car
.
Upvotes: 1
Reputation: 51561
There are several comparison operators. The general ones are eq
, eql
, equal
and equalp
. Look them up in the hyperspec.
For objects of specific types, there are often specialized comparators, e.g. string=
and char=
.
Finally, for list operations, there are functions like member
, which can free you from writing loops by hand. They take an optional test
parameter, through which you can pass the comparison function.
Upvotes: 1