2012-02-20 62 views
5

我有一個函數想要根據優先級順序從地圖中提取一個值。目前我正在將它作爲一個嵌套的if結構,這是非常可怕的。我必須相信還有更好的辦法。Clojure從基於優先級邏輯的地圖提取值

雖然這個工程有更好的方法嗎?

(defn filter-relatives [relatives] 
    (if(contains? relatives :self) 
     (relatives :self) 
      (if(contains? relatives :north) 
       (relatives :north) 
        (if(contains? relatives :west) 
         (relatives :west) 
         (if(contains? relatives :east) 
          (relatives :east) 
          (relatives :south) 
         ) 
        ) 
       ) 
      ) 
     ) 
    ) 
) 

回答

9
(some relatives [:self :north :west :east :south]) 
+1

這是正確的答案。 – 2012-02-20 19:45:21

+1

...除非你還想獲取零值。 – 2012-02-20 20:13:56

+3

...或「假」。如果這是一個問題,請參閱我的答案進行適當的調整,否則一定要使用這一個。 – 2012-02-20 20:52:12

5

什麼:

(defn filter-relatives [relatives ordered-filters] 
    (first (filter identity (map relatives ordered-filters)))) 

採樣運行:

user=> (filter-relatives {:a 1 :b 2 :c 3} [:z :b :a])                
2 
5

其他的答案是好的,如果nilfalse沒有可能值當中。如果他們是,你可以使用類似於

(if-let [e (some (partial find relatives) 
       [:self :north :west :east :south])] 
    (val e) 
    :no-key-found) 

例如,

(if-let [e (some (partial find relatives) 
       [:self :north :west :east :south])] 
    (val e) 
    :no-key-found) 
; => false 

(if-let [e (some (partial find {}) 
       [:self :north :west :east :south])] 
    (val e) 
    :no-key-found) 
; => :no-key-found 
1
(first (keep relatives [:self :north :west :east :south]))