【问题标题】:Return Highest Key value Pair inside of an Array Map in Clojure在 Clojure 中返回数组映射内的最高键值对
【发布时间】:2014-10-03 19:27:37
【问题描述】:

我有一个返回以下数组映射的函数:

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

我想返回 2,因为它有最高的键,499。 最好的方法是什么?

【问题讨论】:

标签: sorting clojure array-map


【解决方案1】:

如果您的地图很大,这不是最有效的方法,但它确实有效:

(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

【讨论】:

  • 但是,如果只通过一次就足够了,为什么要对整个列表进行排序呢?
  • 没有理由,这只是我的第一个想法。也许它比 max-key 解决方案更具可读性。如果地图很短,排序就会在噪音中丢失。如果它很大,那当然最好做一遍。
  • 好吧,我还是认为OP无论如何选择了错误的数据结构,输入只是一个地图的解决方案绝对清晰易读。我不明白为什么要使用这样的地图(或地图数组),其中每个地图只是一对值。
【解决方案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}}))

这会找到映射中具有最高第一个键的第一个(按规范是唯一的?)条目的值。

【讨论】:

    【解决方案3】:

    如果您想表示数字之间的关系,则不需要地图。你可能需要一张这样的地图:

    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
    

    【讨论】:

    • 给了我一张地图,而不是你改成的那张地图。所以这个答案不起作用。
    • 此答案基于推荐。 “给我一张地图”是什么意思?你的意思是你从一些你不能改变的功能中得到一张地图?我对此表示怀疑,因为不需要这种数据结构。 Map 可以包含许多对'key -> value',因此您可以使用一个单独的地图获得具有键 498 的值 3 和具有键 99 或 -99 的值 2。除非您绝对必须使用密钥 {498 3} 来获得价值 {-498 3},否则这种数据组织绝对没有意义。这不是惯用的。即使你希望能够通过键{498 3}得到{-498 3},你也可以编写一个函数
    • ...只是否定地图的第一个元素。请告诉我为什么要使用地图地图?
    • 因为是另一个函数的返回值。
    【解决方案4】:

    试试这个:

    (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}}))))
    

    【讨论】:

      【解决方案5】:

      在您的问题中,您显示了一个地图,其中地图作为键和值。但是您似乎希望将键和值视为正常序列中的元素,所以我猜您实际上的意思如下:

      [{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 在这里不被调用(实际上它很少合适)。
      • 但是,如果只通过一次就足够了,为什么要对整个列表进行排序呢?
      • @Mark:你是对的。我纠正了它。它并不漂亮,但至少现在它是 O(n) 而不再是 O(n*log(n))。 ;-) 你能告诉我如何让代码更简洁吗?
      • @Dobi,到目前为止,Noisesmith 有最简洁的基于max-key 的解决方案(我的基于推荐,所以不太正确),所以看看his answer。但是我发现它很难阅读。
      • 不;我不是“实际上是指以下”;这不适用于所提出的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-29
      • 2021-08-10
      • 1970-01-01
      • 1970-01-01
      • 2011-09-10
      • 2021-06-11
      相关资源
      最近更新 更多