user3245240
user3245240

Reputation: 255

Return Highest Key value Pair inside of an Array Map in Clojure

I have a function that is returning the following array map:

{{498 3} {-498 3}, {99 2} {-99 2}, {499 2} {-499 2}, {100 1} {-100 1}}

And I'd like to return 2, because it has the highest key, 499. Whats the best way to do this?

Upvotes: 2

Views: 489

Answers (5)

Tobias Hermann
Tobias Hermann

Reputation: 10936

In you question you show a map with maps as keys and as values. But it seems you want to treat the keys and values like elements in a normal sequence, so I guess you actually meant the following:

[{498 3} {-498 3} {99 2} {-99 2} {499 2} {-499 2} {100 1} {-100 1}]

In that case the this function returns your wished value:

(defn val-for-highest-key
  [s]
  (->> s (map #(into [] %)) (map first) (apply max-key first) second))

test:

(def res [{498 3} {-498 3} {99 2} {-99 2} {499 2} {-499 2} {100 1} {-100 1}])
(val-for-highest-key res)

result:

=> 2

Upvotes: 0

Symfrog
Symfrog

Reputation: 3418

Try this:

(let [fval (comp val first)
      fkey (comp key first)]
  (fval
   (reduce
    (fn [v e] (if (< (fkey v) (fkey e)) e v))
    (keys {{498 3} {-498 3}, {99 2} {-99 2}, {499 2} {-499 2}, {100 1} {-100 1}}))))

Upvotes: 0

Mark Karpov
Mark Karpov

Reputation: 7599

If you want to represent relations between numbers you don't need map of maps. You probably need one map like this:

user> (def foo {498 3, -498 3, 99 2, -99 2, 499 2, -499 2, 100 1, -100 1})
;; => #'user/foo

It is way more idiomatic, believe me, so may be you should consider rewriting function that returns map of maps (or vector of maps).

To solve your actual problem, try using max-key, for it is efficient function created specially for such cases. Here is how you can use it with a map:

user> (second (apply max-key first foo))
;; => 2

Upvotes: 1

noisesmith
noisesmith

Reputation: 20194

((comp val first key)
 (apply max-key
        (comp key first key)
        {{498 3} {-498 3}, {99 2} {-99 2}, {499 2} {-499 2}, {100 1} {-100 1}}))

This finds the value of the first (by spec the only?) entry in the map with the highest first key.

Upvotes: 1

Diego Basch
Diego Basch

Reputation: 13069

Not the most efficient way if your map is large, but it works:

(def am {{498 3} {-498 3}, {99 2} {-99 2}, {499 2} {-499 2}, {100 1} {-100 1}})

(->> am (map key) (sort-by first) last vals first) 

=> 2

Upvotes: 2

Related Questions