Using the min-key function in Clojure

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 #(Mat­h/abs %) -2 1 3)

works, but what if you have a list?  Now you need to get creative:

(apply min-key #(Mat­h/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 #(Mat­h/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…

Technorati Tags:

Published by

Julian Birch

Full time dad, does a bit of coding on the side.

One thought on “Using the min-key function in Clojure”

  1. @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

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s