简体   繁体   English

递归跟踪哈希映射 clojure 中的值

[英]recursively following values in a hash map clojure

I have a problem providing an edge case for the following recursive function that searches hash maps and other similar key,value storage.我在为以下递归函数提供边缘情况时遇到问题,该函数搜索哈希映射和其他类似的键值存储。

(def hashbrownies
  {"Mary","Dave"
   "Dave","Anne"
   "Anne","Tim"})

current approach目前的方法

(defn recursive-lookup
  [key-lst search-func conditional]
  (let [next-key (search-func (first key-lst))]
    (if (conditional next-key)
      (reverse key-lst)
      (recur (cons next-key key-lst) search-func conditional))))

examples that are working有效的例子

>> (recursive-lookup ["Mary"] #(hashbrownies %) (partial = nil))
=> ("Mary" "Dave" "Anne" "Tim")

>> (recursive-lookup ["Mary"] #(hashbrownies %) #(< (.length %) 4))
=> ("Mary" "Dave" "Anne")

Problematic:有问题:

>> (recursive-lookup ["Mary"] #(hashbrownies %) #(> (.length %) 4))
=> NullPointerException   clojure.lang.Reflector.invokeNoArgInstanceMember (Reflector.java:296)

I can see what the problem is: as the condition can not be met, the function #(> (.length %) 4) takes nil (the last possible return value) as an argument.我可以看到问题是什么:由于无法满足条件,函数#(> (.length %) 4)nil (最后一个可能的返回值)作为参数。 But being new to Clojure I am not sure how to cover for this.但是作为 Clojure 的新手,我不确定如何解决这个问题。 Is there an idiomatic way?有没有惯用的方法?

solution:解决方案:

(defn recursive-lookup
  [key-lst search-func conditional]
  (let [next-key (search-func (first key-lst))]
    (if (or (nil? next-key)
            (conditional next-key))
      (reverse key-lst)
      (recur (cons next-key key-lst) search-func conditional))))

You need to handle nil in your conditional function.您需要在条件函数中处理nil You can use fnil for that.你可以使用fnil fnil replaces nil with some default value. fnil用一些默认值替换 nil。 So you can try:所以你可以试试:

(fnil #(> (.length %) 4) "")

If this conditional function receives nil it replaces nil with empty string "" and then call your function #(> (.length %) 4) .如果此条件函数收到nil它将用空字符串 "" 替换nil ,然后调用您的函数#(> (.length %) 4)

Also you can use count instead .length .您也可以使用count代替.length Count returns 0 for nil: Count 为 nil 返回 0:

(count "123") => 3
(count nil) => 0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM