2012-02-20 66 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]))