1

I have a vector of points in 2D space such as:

[[0 0] [1 1] [2 2]]

And need to compute the distance between some point and each point in the vector to determine which point in the vector is closest to the point I'm querying. I need to know both the distance and the closest point, so I want a vector of hashes like this:

[{:point [0 0] :dist 2.7} {:point [1 1] :dist 3.5} {:point [2 2] :dist 4.3}]

How can I transform the former into the latter? I tried something like this:

(defn closest-point [point all-points]
    (map #({:point % :dist (distance point %)}) all-points))

But I get an error:

(user=> ArityException Wrong number of args (0) passed to: PersistentArrayMap  clojure.lang.AFn.throwArity (AFn.java:437)
Josh Glover
  • 25,142
  • 27
  • 92
  • 129

4 Answers4

9

#({...}) expands into (fn [] ({....})) which tries to call the map without any arguments.

Try this:

(defn closest-point [point all-points]
    (map (fn [p] {:point p :dist (distance point p)}) all-points))

or

(defn closest-point [point all-points]
    (map #(hash-map :point % :dist (distance point %)) all-points))

or

(defn dist-info
  [point p]
  {:point p :dist (distance point p)})

(defn closest-point [point all-points]
    (map #(dist-info point %) all-points))
Joost Diepenmaat
  • 17,633
  • 3
  • 44
  • 53
  • Joost, thanks. I had a copy and paste error which omitted the #() around my hash, which I fixed in the question now. Your second solution works perfectly! If you remove the opening paragraph and the first example (which doesn't work), I'll accept your answer. – Josh Glover Dec 12 '11 at 08:51
5

This is more readable if you use a for comprehension instead of a map. Also, to actually select the nearest point, you can just use min-key:

(defn closest-point [point all-points]
  (apply min-key :dist
         (for [p all-points]
           {:point p :dist (distance point p)})))
amalloy
  • 89,153
  • 8
  • 140
  • 205
2

What about fixing it without removing anything from your code and just adding a single word : identity

(defn closest-point [point all-points]
    (map #(identity {:point % :dist (distance point %)}) all-points))
Ankur
  • 33,367
  • 2
  • 46
  • 72
1
(defn closest-point [point all-points]
  (map #(hash-map :point % :dist (distance point %) ) all-points)                                                                 

Result:-

({:point [0 0], :dist 2.7} {:point [1 1], :dist 3.5} {:point [2 2], :dist 4})
djhworld
  • 6,726
  • 4
  • 30
  • 44