2012-11-18 2 views
2

해시 맵 및 기타 유사한 키, 값 저장을 검색하는 다음 재귀 함수에 대해 대소 문자를 구분하는 데 문제가 있습니다.해시 맵에서 값을 재귀 적으로 따라 가기 clojure

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

현재의 접근 방식 문제있는

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

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

작업

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

예 : 조건이 될 수 없다 같이

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

나는 문제가 무엇인지 볼 수 있습니다 만났을 때, 기능은 #(> (.length %) 4)은 인수로 nil (가능한 마지막 반환 값)을 사용합니다. 그러나 Clojure를 처음 접했을 때 나는 이것을 어떻게 커버해야할지 모르겠다. 관용적 인 방법이 있습니까?

솔루션 :

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

답변

2

당신은 조건부 기능에 nil을 처리해야합니다. 그것에 대해 fnil을 사용할 수 있습니다. fnil은 nil을 일부 기본값으로 바꿉니다. 이 조건 함수가 빈 문자열로 nil을 대체 nil을받는 경우 "

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

을"다음 기능 #(> (.length %) 4) 전화 : 그래서 당신은 시도 할 수 있습니다.

도 대신 count을 사용할 수 있습니다. Count는 nil에 대해 0을 반환합니다.

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

기본 값 또는 0을 얻으면 함수가 목록에 추가하고 힙 공간이 부족하여 다시 호출합니다. 목록을 반환하지 않으려면 main 함수를 변경해야한다고 생각합니다. 아마도 '사례'진술일까요? – beoliver

+1

예, 주요 기능을 수정해야한다고 생각합니다. 'if'에 조건을 추가 할 수 있습니다 :'(if (또는 (nil? next-key) (조건부 next-key))) ...)' –

+0

위대한! 대답을 보여주기 위해 내 질문을 업데이트 할 것입니다. – beoliver

관련 문제