Clojure value extraction from map based on priority logic

I have a function that wants to infer a value from a map based on priority order. I am currently doing this as a nested structure that is terrible. I have to believe that there is a better way.

While this works, is there a better way?

(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)
                         )
                     )
                 )
              )
          )
    )
)
+5
source share
4 answers
(some relatives [:self :north :west :east :south])
+9
source

What about:

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

Run Example:

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

The other answers are good if niland falseare not included in the number of possible values. If they are, you can use something like

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

eg.

(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
+5
source
(first (keep relatives [:self :north :west :east :south]))
+1
source

All Articles