2012-02-20 6 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

これが正解です。 –

+1

... nil値も取得しない場合は除きます。 –

+3

...または 'false'それが問題であれば、適切な調整については私の答えを見てください。 –

5

何について:

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

サンプル実行:nilfalseが可能な値の中でない場合

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

他の答えは罰金です。もしそうなら、あなたは何かを使用することができます。

(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])) 
関連する問題