sorted-map returns nil value for existing key

﹥>﹥吖頭↗ 提交于 2019-12-23 17:37:06

问题


I try to get value by key from sorted map with comparator by value it returns 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

Expected: {:v 3}

Actual: nil


回答1:


You are creating a custom Comparator with compare that is being used in PersistentTreeMap (the type of tmap-sorted) to lookup the value but your comparator never returns 0 which would mean that two objects are equal.

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.

If you modify your comparator to println for debug you can see that when compare 3 to 3 you get 1 meaning they are not equal.

(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

So you need to fix your compare function to work for equality



来源:https://stackoverflow.com/questions/42231882/sorted-map-returns-nil-value-for-existing-key

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!