我需要将 max 运算符应用于以下列表
[Tier20 Tier10 Tier30]
它应该给我
Tier30
预定义的有序列表(从低到高)是
[Tier5 Tier10 Tier20 Tier30 Tier40 Tier50]
在 Clojure 中实现这一目标的最佳方法是什么?
我需要将 max 运算符应用于以下列表
[Tier20 Tier10 Tier30]
它应该给我
Tier30
预定义的有序列表(从低到高)是
[Tier5 Tier10 Tier20 Tier30 Tier40 Tier50]
在 Clojure 中实现这一目标的最佳方法是什么?
首先定义排序:
user> (def order '[Tier5 Tier10 Tier20 Tier30 Tier40 Tier50])
#'user/order
然后我们将订单映射到可以通过创建一个排序的东西上map
user> (def order-map (zipmap order (range)))
{Tier50 5, Tier40 4, Tier30 3, Tier20 2, Tier10 1, Tier5 0}
如果您只需要最大/最小值,请使用 order-map 来减少输入:
user> (reduce #(if (< (order-map %1) (order-map %2)) %1 %2)
'[Tier20 Tier10 Tier30])
Tier30
user> (sort-by (zipmap order (range)) '[Tier20 Tier10 Tier30])
(Tier10 Tier20 Tier30)
如果您需要大量修改此地图而不是每次都重新排序,则使用数据sorted-set-by
结构来存储您的输入。
使用减少。例如,要找到列表 L 的最大值,您可以:
(reduce max L)
这里真正的问题是您的层是字符串还是更复杂的对象,因为从您的帖子中并不完全清楚。无论哪种方式,您都可以用 lambda 表达式替换 max 以提取字符串的数字部分,如下所示:
(reduce (fn [x y] ...) L)
其中 ... 将是从数据中提取数字部分的表达式。
这是我刚刚尝试过的。杠杆的要点是实例方法.indexOf
。clojure.lang.Vector
user> (def x ['Tier5 'Tier10 'Tier20 'Tier30 'Tier40 'Tier50])
#'user/x
user> (index-of x 'Tier10)
; Evaluation aborted.
user> (.indexOf x 'Tier10)
1
user> (def y ['Tier20 'Tier10 'Tier30])
#'user/y
user> (reduce #(max %1 (.indexOf x %2)) y)
; Evaluation aborted.
user> (x (reduce #(max %1 (.indexOf x %2)) 0 y))
Tier30
user>
当然,这是 O(n 2 )。如果您要大规模执行此操作,那么从 TierN 到其排序索引的哈希映射会为您提供更好的服务。
如果数组是这样的,java.lang.String
则具有一些互操作性:
user=> (def array ["Tier5" "Tier10" "Tier20" "Tier30" "Tier40" "Tier50"])
#'user/array
user=> (defn find-max [m] (reduce #(if (> (.compareTo %1 %2) -1) %1 %2) m))
#'user/find-max
user=> (find-max array)
"Tier50"
user=> (find-max "a")
\a
如果不只是让它们实现Comparable
,或者创建一个 Comparator
.