2017-02-14 8 views
2

Я пытаюсь получить значение по ключу из сортированной карты с компаратором по значению, которое возвращает nil.CLOJURE sorted-map возвращает значение 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}

Actual: nil

+1

я не знаю о том, почему он не возвращает ожидаемое значение, но я, если и пытается достичь же тогда есть еще один способ , попробуйте эти (получить (в (отсортированные карты) tmap) 3) – piyushmandovra

+2

Ваша функция сравнения асимметрична, так как '(fxy) = 1' и' (fyx) = 1' когда '(get-in tmap [x : v]) (get-in tmap [y: v]) 'is' 0'. – Lee

ответ

5

Вы создаете пользовательский Comparator с compare, который используется в PersistentTreeMap (тип tmap-sorted) для поиска значения, но ваш компаратора не возвращается 0, что означает, что два объекта равны.

https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html

следует соблюдать осторожность при использовании компаратора, способный устанавливающего порядок несовместимым с равными заказать отсортированный набор (или отсортированную карту). Предположим, что отсортированный набор (или отсортированная карта) с явным компаратором c используется с элементами (или ключами), взятыми из набора S. Если порядок, наложенный c на S, несовместим с равными, отсортированный набор (или отсортированная карта) будет ведут себя «странно». В частности, сортированный набор (или отсортированная карта) нарушит общий контракт для множества (или карты), который определяется в терминах равных.

Если вы измените компаратор println для отладки вы можете увидеть, что при сравнении к вы получаете означает, что они не равны.

(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 функции для работы равенства

+0

Да, это правильно. Благодарю. –

 Смежные вопросы

  • Нет связанных вопросов^_^