Clojure 排序映射返回现有键的nil值
我尝试从排序后的映射中按键获取值,比较器返回值Clojure 排序映射返回现有键的nil值,clojure,Clojure,我尝试从排序后的映射中按键获取值,比较器返回值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])))]
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
应为:{:v3}
实际值:nil
您正在创建一个自定义值,该自定义值在(排序的tmap类型)中用于查找值,但您的比较器从不返回0,这意味着两个对象相等
当使用比较器时,应谨慎使用,比较器能够对排序集(或排序映射)施加与等于不一致的排序。假设一个带有显式比较器c的排序集(或排序映射)与从集合S中提取的元素(或键)一起使用。如果c对S施加的顺序与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
函数来实现相等我不知道为什么它不返回期望值,但是如果你试图实现相同的值,那么还有一种方法。尝试这些(进入(按>排序的地图)tmap)3)你的比较函数是不对称的,因为(fxy)=1
和(fyx)=1
当(进入tmap[x:v])(进入tmap[y:v])
为0
时。