2017-02-14 56 views
2

我尝试通过键值从有排序的映射获得值,比较器按值返回nilCLOJURE排序映射为现有密钥返回零值

(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}

实际:nil

+1

我不知道为什么它没有返回预期值的工作,但雅如果你企图达到同样那么还有一个办法。 3) – piyushmandovra

+2

你的比较函数是不对称的,因为'(fxy)= 1'和'(fyx)= 1'当'(get-in tmap [x :v])(get-in tmap [y:v])'是'0'。 – Lee

回答

5

您正在创建一个自定义Comparator与在PersistentTreeMap(的tmap-sorted类型)被用来compare查找值,但你比较不会返回0这意味着两个对象是相等的。

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

应谨慎使用能够施加的排序不一致与equals订购有序集合(或有序映射)的比较器时行使。假设使用显式比较器c的排序集合(或排序映射)与从集合S中绘制的元素(或键)一起使用。如果由S对c施加的排序与equals不一致,则排序集合(或排序映射)将表现“奇怪”。特别是,排序后的集合(或排序后的映射)将违反集合(或映射)的一般合约,集合(或映射)以等式定义。

如果修改比较来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

是的,它是正确的。谢谢。 –