我尝试从排序映射中按键获取值,并按比较器返回的值nil
。
(def tmap {1 {:v 1} 2 {:v 2} 3 {:v 3}})
(def tmap-sorted
(apply sorted-map-by
#(let [val-comp (- (compare
(get-in tmap [%1 :v])
(get-in tmap [%2 :v])))]
(if (= val-comp 0)
1
val-comp))
(flatten (vec tmap))))
; => {3 {:v 3} 2 {:v 2} 1 {:v 1}}
(get tmap-sorted 3)
;=> nil
预期:{:v 3}
实际:无
最佳答案
您正在创建自定义 Comparator与 compare
正在 PersistentTreeMap
中使用(tmap-sorted
的类型)来查找值,但比较器永远不会返回 0,这意味着两个对象相等。
https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html
Caution should be exercised when using a comparator capable of imposing an ordering inconsistent with equals to order a sorted set (or sorted map). Suppose a sorted set (or sorted map) with an explicit comparator c is used with elements (or keys) drawn from a set S. If the ordering imposed by c on S is inconsistent with equals, the sorted set (or sorted map) will behave "strangely." In particular the sorted set (or sorted map) will violate the general contract for set (or map), which is defined in terms of equals.
如果您将比较器修改为 println
进行调试,您可以看到,当比较 3 与 3 时,您会得到 1 意味着它们不相等。
(def tmap {1 {:v 1} 2 {:v 2} 3 {:v 3}})
(def tmap-sorted (apply
sorted-map-by
#(let [val-comp
(- (compare
(get-in tmap [%1 :v])
(get-in tmap [%2 :v])))
ret (if (= val-comp 0)
1
val-comp)]
(println "%1: " %1 " %2: " %2 " ret=" ret)
ret)
(flatten (vec tmap))))
(get tmap-sorted 3)
;; %1: 3 %2: 2 ret= -1
;; %1: 3 %2: 3 ret= 1
(get tmap-sorted 1)
;; %1: 1 %2: 2 ret= 1
;; %1: 1 %2: 1 ret= 1
因此,您需要修复您的 compare
函数以实现相等
关于clojure - 排序映射对现有键返回 nil 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42231882/