Clojure中最高键值的返回值

问题描述:

我正在处理这两组键值对,它们被另一个函数返回。我想写一个函数,它总能找到最高的键并返回相应的值。在这个例子中,我会返回2,因为499是最高的关键。我正在处理的数据是Clojure中最高键值的返回值

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

当我打电话

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

内,负责其返回该数据的功能,我回来

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

我希望帮助。谢谢!

+1

显然你的意思'(图型对)' – 2014-10-01 17:17:27

+0

怎么办你想解决重复的最大密钥? – Jeremy 2014-10-01 22:32:28

({-99 0, 99 0} {-99 2, 499 2})是查找操作,其中{-99 0, 99 0}是字典而{-99 2, 499 2}是关键。由于后者不是前者的关键,表达式将返回零。

当我评估(type ({-99 0, 99 0} {-99 2, 499 2}))时,我得到nil,因为nil的类型也是nil

+3

这不是一个操作,它是一个列表,“由另一个函数返回”。 – 2014-10-01 17:16:44

(as-> (apply merge pair) 
     merged 
     (->> merged 
      keys 
      (apply max) 
      merged)) 

请注意,当两个图都具有“最高”键时,将返回第二个值。

这是一个很好的用例max-key,我认为有一种误导的名字(其使用的一个很好的例子见this other SO question) - 它实际上做的是它需要一个功能的集合,它返回集合中具有将该函数应用于该项目的最高结果的项目。您可以使用函数key,该函数返回键值对的键。

(请注意,您需要一起Concat的您的地图让你与键值对的单一收集。)

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

(second *1) 
;=> 2 
+0

我会注意到,如果有重复键,最右边的值将被选中。 '(apply max-key key(concat {-99 0,499 0} {-99 2,499 2})); => [499 2]' – Jeremy 2014-10-01 22:38:11

+1

你是对的......这会导致问题,如果最右边关键不是价值最高的那个。有趣的是,'(concat {-99 0,499 5} {-99 2,499 2})'自己返回一个* *包含重复键的列表:'([-99 0] [499 5] [ - 99 2] [499 2])'。但是,通过执行'(apply max-key key ...)'似乎将这些键强制转换为java.util.Map $ Entry'键值对,并通过使用最右边的键来消除重复项,不正确的(注意我改变了最左边一个的值> 2)'[499 2]'的答案。 – 2014-10-02 17:41:51

+0

实际上,在进一步的回顾中,'[499 2]'在技术上没有错误--OP只是寻找一种方式返回最高* key *的值,即499.那么问题是该键有两个值,无论如何,我仍然认为'max-key'是一个很好的解决方案,假设你'这是一个没有重复键的地图 – 2014-10-02 17:46:16

(defn val-for-max-key [maps] 
    (->> (map (partial apply max-key key) maps) 
     (apply max-key key) 
     val)) 

编辑: 误解所需的返回值

+0

'(val-for-max-key'({-99 0,99 5000} {-99 2,499 2})); => 5000' – Jeremy 2014-10-01 22:31:05

此函数将返回对数时间

01中Clojure排序映射(内置实现称为 clojure.lang.PersistentTreeMap)的最右项
(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))) 

例子:

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

然后,您可以捞出用val函数的值。

所有max-key/apply max为基础的解决方案线性时间,而不是工作。不用说,这是一个巨大的差异。

如果其他功能可以被说服重返data.avl映射相反,你可以使用nth在对数时间任何索引访问元素:

;; works for data.avl sorted maps, not the built-ins 
(nth (avl/sorted-map 1 1 2 2 3 3) 2) 
;= [3 3]