2012-02-20 11 views
5

Tengo una función que desea extraer un valor de un mapa en función de un orden priorizado. Actualmente lo estoy haciendo como una estructura anidada que es horrible. Tengo que creer que hay una mejor manera.Clojure extrae el valor del mapa según la lógica priorizada

Mientras esto funciona, ¿hay una mejor manera?

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

Respuesta

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

Esta es la respuesta correcta. –

+1

... a menos que también desee obtener valores nulos. –

+3

... o 'falso'. Si se trata de un problema, consulte mi respuesta para un ajuste apropiado; de lo contrario, definitivamente use este. –

5

¿Qué hay de:

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

Muestra de ejecución:

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

Las otras respuestas son bien si nil y false no se encuentran entre los valores posibles. Si lo son, puede usar algo como

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

P. ej.

(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])) 
Cuestiones relacionadas