Return value of highest key in Clojure

2019-08-10 22:26发布

I'm working with these two groups of key value pairs, which is being returned by another function. I'd like to write a function that will always find the highest key and return its corresponding value. In this example, I'd be returning 2 because 499 is the highest key. The data that I am working with is

({-99 0, 99 0} {-99 2, 499 2})

When I call

   (type ({-99 0, 99 0} {-99 2, 499 2}))

Within the function that is responsible for returning that data it, I get back

 (clojure.lang.PersistentTreeMap clojure.lang.PersistentTreeMap)

I hope that helps. Thanks!

5条回答
\"骚年 ilove
2楼-- · 2019-08-10 22:52
(defn val-for-max-key [maps]
  (->> (map (partial apply max-key key) maps)
       (apply max-key key)
       val))

EDIT: misunderstood desired return value

查看更多
对你真心纯属浪费
3楼-- · 2019-08-10 23:03
(as-> (apply merge pair)
      merged
      (->> merged
           keys
           (apply max)
           merged))

Notice that when both maps have a "highest" key, the value of second one is returned.

查看更多
干净又极端
4楼-- · 2019-08-10 23:04

This is a good use case for max-key (See this other SO question for a good example of its use), which I think has kind of a misleading name -- what it actually does is it takes a function and a collection, and it returns the item in the collection that has the highest result of applying the function to that item. You can use the function key, which returns the key of a key-value pair.

(Note that you need to concat your maps together so that you're working with a single collection of key-value pairs.)

(apply max-key key (concat {-99 0, 99 0} {-99 2, 499 2}))
;=> [499 2]

(second *1)
;=> 2
查看更多
戒情不戒烟
5楼-- · 2019-08-10 23:09

({-99 0, 99 0} {-99 2, 499 2}) is a lookup operation, where {-99 0, 99 0} is a dictionary and {-99 2, 499 2} is a key. Since the latter is not a key in the former, the expression will return nil.

When I evaluate (type ({-99 0, 99 0} {-99 2, 499 2})), I get nil, because the type of nil is also nil.

查看更多
做自己的国王
6楼-- · 2019-08-10 23:17

This function will return the rightmost entry of a Clojure sorted map (the built-in implementation is called clojure.lang.PersistentTreeMap) in logarithmic time:

(defn rightmost
  "Takes a Clojure sorted map sm and returns the entry at the greatest
  key (as determined by sm's comparator)."
  [sm]
  (first (rseq sm)))

Example:

(rightmost (sorted-map 1 1 2 2 3 3))
;= [3 3]

You can then fish out the value using the val function.

All the max-key / apply max-based solutions work in linear time instead. Needless to say, it's a huge difference.

If the other function could be convinced to return data.avl maps instead, you could access the element at any index in logarithmic time using nth:

;; works for data.avl sorted maps, not the built-ins
(nth (avl/sorted-map 1 1 2 2 3 3) 2)
;= [3 3]
查看更多
登录 后发表回答