I was discussing today at work the problem of dealing with a variable length list of parameters in a typeless language. If you explicitly declare the variable part of your parameters to be a list of strings, if someone only passes in one parameter, the compiler can check if it’s a list of string or a single string and compile accordingly. Without the type information (which ironically, includes C) you’re out of luck. It’s got to assume you are dealing with a list.
So, if you’ve got a list and you want the smallest item in Clojure
(min [-2 1 3])
will just return [-2 1 3]. Not really a useful behaviour. However, you can use apply to solve the problem:
(apply min [-2 1 3])
actually returns -2. It gets trickier, though, when you’re dealing with min-key. Let’s say you want the number that’s closest to zero.
(min-key #(Math/abs %) -2 1 3)
works, but what if you have a list? Now you need to get creative:
(apply min-key #(Math/abs %)) [-2 1 3])
This relies on the fact that apply always takes the last parameter and flattens it. So (apply f a b [c d e]) is the same as (f a b c d e).
CORRECTION: My original solution to this was
((partial apply min-key #(Math/abs %)) [-2 1 3])
which I didn’t really like. I invited alternatives in the comments, and got a superior one from Huw. I’ve replaced the main text with his solution. I’ve also learned a bit more Clojure, which is the point of blogging in the first place…
One thought on “Using the min-key function in Clojure”
@Paul – those two forms do different things:(apply min (map #(Math/abs %) [-2 -1 3]))=> 1(apply min-key #(Math/abs %) [-2 -1 3])=> -1