Sorting Clojure:按嵌套映射自定义比较器排序
我有一个嵌套的Clojure映射:Sorting Clojure:按嵌套映射自定义比较器排序,sorting,clojure,Sorting,Clojure,我有一个嵌套的Clojure映射: { :1 { :priority "Medicore" :somekey "SomeValue" }, :2 { :priority "Enormous" :somekey "SomeValue" }, :3 { :priority "Weeny" :somekey "SomeValue" } } 我的目标是从具有“最高”优先级的映射中获取somekey的值。外部映射可以包含0-n个具有
{
:1 {
:priority "Medicore"
:somekey "SomeValue"
},
:2 {
:priority "Enormous"
:somekey "SomeValue"
},
:3 {
:priority "Weeny"
:somekey "SomeValue"
}
}
我的目标是从具有“最高”优先级的映射中获取somekey
的值。外部映射可以包含0-n个具有三个优先级中任意一个的元素。如果有多个条目具有最高的可用优先级,我可以选择任何一个条目
在研究了其他一些SO问题之后,我认为解决这个问题的一个好方法是使用排序方式
函数。但由于我的优先级
不是自然排序的,所以我必须提供一些自定义比较器
这可能吗?对于我的目标,我的方法是否正确?要使用
排序方式,您需要提供排序或优先级值。您可以实现一个自定义比较器来比较地图,或者为排序依据定义一个键fn,用于计算用于排序的键。下面是使用keyfn的解决方案。仅使用keyfn返回一个与您的需求相匹配的可比值要比实现comparator容易得多。你可能想看看
我们开始定义一个函数,将字符串优先级转换为其数值表示形式:
(let [priorities {"Medicore" 0
"Enormous" 1
"Weeny" 2}]
(defn priority->num [p]
(if-let [num (priorities p)]
num
(throw (IllegalArgumentException. (str "Unknown priority: " p))))))
(priority->num "Enormous")
;; => 1
现在我们需要计算每个地图的最大优先级:
(defn max-priority-num [m]
(->> m
(vals)
(map (comp priority->num :priority))
(apply max)))
(max-priority-num {:1 {:priority "Medicore" :somekey "SomeValue"}
:2 {:priority "Enormous" :somekey "SomeValue"}
:3 {:priority "Weeny" :somekey "SomeValue"}})
;; => 2
现在我们终于可以使用排序方式了
:
(def m1 {:1 {:priority "Medicore" :somekey "SomeValue"}
:2 {:priority "Medicore" :somekey "SomeValue"}
:3 {:priority "Weeny" :somekey "SomeValue"}})
(def m2 {:1 {:priority "Medicore" :somekey "SomeValue"}
:2 {:priority "Enormous" :somekey "SomeValue"}
:3 {:priority "Weeny" :somekey "SomeValue"}})
(def m3 {:1 {:priority "Medicore" :somekey "SomeValue"}
:2 {:priority "Medicore" :somekey "SomeValue"}
:3 {:priority "Medicore" :somekey "SomeValue"}})
(sort-by max-priority-num [m1 m2 m3])
;; =>
({:1 {:priority "Medicore", :somekey "SomeValue"},
:2 {:priority "Medicore", :somekey "SomeValue"},
:3 {:priority "Medicore", :somekey "SomeValue"}}
{:1 {:priority "Medicore", :somekey "SomeValue"},
:2 {:priority "Medicore", :somekey "SomeValue"},
:3 {:priority "Weeny", :somekey "SomeValue"}}
{:1 {:priority "Medicore", :somekey "SomeValue"},
:2 {:priority "Enormous", :somekey "SomeValue"},
:3 {:priority "Weeny", :somekey "SomeValue"}})
使用max key
比使用sort by
容易得多。对@amalloy,我想得到max元素,而不是所有元素都排序!因此,与其调用(按最大优先级num[m1 m2 m3]排序),(最大键最大优先级num m1 m2 m3)
或(应用最大键最大优先级num映射)
会更好。