Is there simple way ho to ignore unnecessary arguments?
For example:
(#(+ %1 %2) 1 2)
returns 3
I would like to force this code
(#(+ %1 %2) 1 2 3)
to returns 3 too. But it returns
java.lang.IllegalArgumentException: Wrong number of args (3) passed to.
How to change #(+ %1 %2)
?
I hope there is some more elegant way than #(+ (nth %& 0) (nth %& 1))
.
Here's what I would go with:
=> ((fn [a b & _] (+ a b)) 1 2 3)
=> 3
This creates an anonymous function that takes any number of arguments, but just adds the first two. The _
symbol isn't doing anything special, it's just idiomatic for "I don't care about this thing, but I need it bound somehow". If you think you are going to be doing this a lot, then you would probably want to define it:
(defn add-first-two
[a b & _]
(+ a b))
If you are really into the #()
syntax, you will have to include %&
somewhere in the definition for it to "realize" that it should take any number of arguments. It doesn't mean you would have to index it as you show, it would just have to be present somewhere. Here's an example:
=> (#(do %& (+ %1 %2)) 1 2 3)
=> 3
On the other hand, this solution involves some sort of processing of %&
, where you don't need any, and may slow things down slightly (I'm not sure about this, maybe someone else can give me feedback on this). A rather fun solution would be to just stick %&
inside a (comment ...)
block, which will evaluate to nil
.
=> (#(do (comment %&) (+ %1 %2)) 1 2 3)
=> 3
An even more exotic solution would be to use #_...
, which is a lot like (comment...)
except that the reader actually removes it from evaluation, as though you had simply typed nothing there. This way, maybe we could stick it inside the body of (+ ...)
to shorten the code.
=> (#(+ %1 %2 #_%&) 1 2 3)
=> 3
What do you know, it worked. I'd actually never tried this one before, and I am pretty surprised to see it work. Apparently, there is some processing before the #_...
section is removed. Strange.
If you don't like any of these weird comment solutions, and the do
isn't doing it for you, you could always put it inside an (if nil ...)
block:
=> (#(if nil %& (+ %1 %2)) 1 2 3)
=> 3
Well, after all that, I still like the first solution best (using (fn ...)
), but some of these others are certainly shorter.
This works for any number of arguments, and is readable:
(fn [& args] (apply + args))
If you only want to use the first 2 arguments (as per Alex' comment):
(fn [& args] (apply + (take 2 args)))
You can use it directly:
((fn [& args] (apply + (take 2 args))) 1 2)
; => 3
Or bind the function to a symbol like this:
(let [f (fn [& args] (apply + (take 2 args)))]
(f 1 2))
; => 3
Or create a var:
(def f (fn [& args] (apply + (take 2 args))))
Or a function:
(defn f [& args] (apply + (take 2 args)))
The best definition depends on your use case.
how about this?
(#(apply + (take 2 %&)) 1 2 3 4 5)
;; => 3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With