首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Clojure:排序映射在合并和重复操作上下文中的不稳定行为?

Clojure:排序映射在合并和重复操作上下文中的不稳定行为?
EN

Stack Overflow用户
提问于 2014-10-11 08:52:24
回答 1查看 103关注 0票数 1

我有下面的代码段。它能正常工作。

代码语言:javascript
复制
(use '(incanter.stats))

(defmacro dbg [body]
      `(let [x# ~body]
         (println "dbg:" '~body "=" x#)
         x#))

(defn sorted-map-by-values
  "create a map sorted in descending order, first by value, then by key"
  [super-map & reverse]
  (dbg "Start to sort")
  (dbg super-map)
  (let [compare-value (if (nil? reverse) 1 -1)]
    (into (sorted-map-by
           (fn [key1 key2]
             (let [val1 (super-map key1) val2 (super-map key2)]
               (cond
                (= val1 val2) (.compareTo (str key2) (str key1)) ; use string representation of list, to overcome that there is no .compareTo for AarrySeq
                (< (dbg val1) (dbg val2)) compare-value
                :else (- compare-value)))))
          super-map))
  )

(def search (clojure.string/split "garbage stuff" #"\s"))

(def candidate (clojure.string/split "stuff" #"\s"))

(sorted-map-by-values (let [pairs-init (for [x search y candidate] [x y])]
                            (loop [pairs pairs-init distance-map {}]
                              (if (empty? pairs)
                                distance-map
                                (let [pair (sort (first pairs))
                                      updated-map (if (nil? (get distance-map pair))
                                                    (merge distance-map {pair (apply incanter.stats/levenshtein-distance pair)})
                                                    distance-map)]
                                  (recur (rest pairs) updated-map))))) 
                          true)

但如果我将最后一份表格改为:

代码语言:javascript
复制
(let [pairs-init (for [x search y candidate] [x y])]
  (loop [pairs pairs-init distance-map {}]
    (if (empty? pairs)
      distance-map
      (let [pair (sort (first pairs))
            updated-map (if (nil? (get distance-map pair))
                          (sorted-map-by-values ; <- move sorted-map-by-values to here
                           (merge distance-map {pair (apply incanter.stats/levenshtein-distance pair)})
                           true)
                          distance-map)]
        (recur (rest pairs) (dbg updated-map))))))

然后我发现了一个错误:

代码语言:javascript
复制
java.lang.NullPointerException: null
            Numbers.java:961 clojure.lang.Numbers.ops
            Numbers.java:219 clojure.lang.Numbers.lt
            (Unknown Source) user/sorted-map-by-values[fn]
           AFunction.java:47 clojure.lang.AFunction.compare
  PersistentTreeMap.java:311 clojure.lang.PersistentTreeMap.doCompare
  PersistentTreeMap.java:298 clojure.lang.PersistentTreeMap.entryAt
  PersistentTreeMap.java:278 clojure.lang.PersistentTreeMap.valAt
  PersistentTreeMap.java:283 clojure.lang.PersistentTreeMap.valAt
                 RT.java:645 clojure.lang.RT.get

似乎这一错误发生在线上:

代码语言:javascript
复制
(< (dbg val1) (dbg val2)) compare-value

dbg跟踪如下:

代码语言:javascript
复制
Instarepl:  
dbg: Start to sort = Start to sort
Instarepl:  
dbg: super-map = {(garbage stuff) 7}
Instarepl:  
dbg: updated-map = {(garbage stuff) 7}
Instarepl:  
dbg: val1 = nil
Instarepl:  
dbg: val2 = 7

当地图中只有一个映射时,不应该调用比较器函数,这是没有意义的。通过对代码的跟踪,这个错误似乎实际上发生在循环的第二次迭代中,因为更新后的map值的dbg跟踪显示,包括从按映射排序的值返回的第一次迭代是成功的,但是我无法显示到sorted-map-by-values的第二个条目,似乎还有一个未知的sorted-map-by-values条目。

我想排序映射可能是另一种类型,不能再次应用于排序的值?

您能透露一些奇怪的行为吗?或者我忽略了Clojure语言执行模型的某些部分,这与懒惰评估有关吗?

非常感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-11 11:57:33

问题是distance-map是一个排序映射,这意味着任何conj都将调用排序fn。在您的例子中,merge是尝试执行conj的人。

更长的说明:在循环的第二次迭代中,distance-mapsorted-map的一个实例,然后与{pair (apply incanter.stats/levenshtein-distance pair)}合并。注意,这个merge在第二次调用sorted-map-by-values之前称为

这意味着merge试图将对[(stuff stuff) 0]添加到sorted-map中,这意味着调用排序后的映射的fn排序。该排序fn关闭用于创建它的超级映射的版本,该映射只包含(garbage stuff)键,因此(stuff stuff)的查找为零。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26312835

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档