clojure - 排序映射对现有键返回 nil 值

标签 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])))]
            (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}

实际:

最佳答案

您正在创建自定义 Comparatorcompare正在 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 进行调试,您可以看到,当比较 33 时,您会得到 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/

相关文章:

java - 如何用 Clojure 中动态创建的小部件替换 SeeSaw 小部件?

clojure - 来自 graalvm 的编译图像未打印到标准输出

Clojure defrecord - 如何使用它?跟进

clojure - 在 Clojure 中,如何仅通过记录的一个实例来获取记录的基础?

clojure - 这个函数的返回值是多少?

lisp - 对学习哪种 Lisp 变体有什么建议吗?

java - Clojure 宏实例化异常

java interop的Clojure优化

Clojure:从匿名函数返回一个向量

java - Clojure 相当于 Python 的 lxml 库?