【发布时间】:2014-10-03 19:27:37
【问题描述】:
我有一个返回以下数组映射的函数:
{{498 3} {-498 3}, {99 2} {-99 2}, {499 2} {-499 2}, {100 1} {-100 1}}
我想返回 2,因为它有最高的键,499。 最好的方法是什么?
【问题讨论】:
我有一个返回以下数组映射的函数:
{{498 3} {-498 3}, {99 2} {-99 2}, {499 2} {-499 2}, {100 1} {-100 1}}
我想返回 2,因为它有最高的键,499。 最好的方法是什么?
【问题讨论】:
如果您的地图很大,这不是最有效的方法,但它确实有效:
(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
【讨论】:
((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}}))
这会找到映射中具有最高第一个键的第一个(按规范是唯一的?)条目的值。
【讨论】:
如果您想表示数字之间的关系,则不需要地图。你可能需要一张这样的地图:
user> (def foo {498 3, -498 3, 99 2, -99 2, 499 2, -499 2, 100 1, -100 1})
;; => #'user/foo
相信我,这更惯用了,所以您可能应该考虑重写返回地图地图(或地图矢量)的函数。
要解决您的实际问题,请尝试使用max-key,因为它是专为此类情况创建的高效功能。以下是如何将它与地图一起使用:
user> (second (apply max-key first foo))
;; => 2
【讨论】:
{498 3} 来获得价值 {-498 3},否则这种数据组织绝对没有意义。这不是惯用的。即使你希望能够通过键{498 3}得到{-498 3},你也可以编写一个函数
试试这个:
(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}}))))
【讨论】:
在您的问题中,您显示了一个地图,其中地图作为键和值。但是您似乎希望将键和值视为正常序列中的元素,所以我猜您实际上的意思如下:
[{498 3} {-498 3} {99 2} {-99 2} {499 2} {-499 2} {100 1} {-100 1}]
在这种情况下,此函数返回您希望的值:
(defn val-for-highest-key
[s]
(->> s (map #(into [] %)) (map first) (apply max-key first) second))
测试:
(def res [{498 3} {-498 3} {99 2} {-99 2} {499 2} {-499 2} {100 1} {-100 1}])
(val-for-highest-key res)
结果:
=> 2
【讨论】:
(second (apply max-key (comp key first) res)) 就足够了。 flatten 在这里不被调用(实际上它很少合适)。
max-key 的解决方案(我的基于推荐,所以不太正确),所以看看his answer。但是我发现它很难阅读。