Reputation: 433
I know this might be a silly question, but I don't get it. I have some data:
(def x (range 1 14))
-> (1 2 3 4 5 6 7 8 9 10 11 12 13)
I want to return a list without "3" for example. Googling "clojure remove item from list" took me to this:
(remove pred coll)
So I tried to use example with even?
:
(remove even? x)
-> (1 3 5 7 9 11 13)
Great! It works with my data! I just need to change pred
. And my first guess would be:
(remove (= 3) x)
java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.IFn
Ok, we don't need to evaluate (= 3)
, so let's put #
before:
(remove #(= 3) x)
clojure.lang.ArityException: Wrong number of args (1)` passed to...
I know it is trivial, but still how can I do it?
Upvotes: 11
Views: 7947
Reputation: 101162
You should use:
(remove #(= 3 %) x)
#(= 3)
does not take a parameter (but remove
tries to pass one to that function).
#(= 3 %)
takes one parameter, and calls =
with that parameter (%
) and 3
.
Upvotes: 9
Reputation:
I like using sets for this kind of thing. So clean..
Remove elements:
(remove #{3 5} [1 2 3 4 5 6 7 8 9])
Keep elements:
(keep #{7 5 3} [1 2 3 4 5 6 7 8 9])
Check if element exists:
(some #{5} [1 2 3 4 5 6 7 8 9])
This works because when a set is used as a function of one argument, it returns the argument if it was inside of the set. In the remove example, the elements 3
and 5
cause the set to return a truthy value: themselves. The same thing happens for both the keep
and some
examples, except that the some
example has the added benefit of returning the first element in your collection that's also in the set.
Upvotes: 17