Clojure基于优先逻辑从地图中提取值

Y. *_*tin 5 conditional clojure map filter

我有一个函数想要根据优先顺序从地图中提取一个值.目前我正在将它作为一个嵌套的if结构,这是非常可怕的.我不得不相信有更好的方法.

虽然这项工作有更好的方法吗?

(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)
                         )
                     )
                 )
              )
          )
    )
)
Run Code Online (Sandbox Code Playgroud)

Jus*_*mer 9

(some relatives [:self :north :west :east :south])
Run Code Online (Sandbox Code Playgroud)

  • ......或者"假".如果这是一个问题,请参阅我的答案进行适当的调整,否则一定要使用这个. (3认同)
  • 嗯,当然,但谁说不然?(如果你的印象是我以某种方式做过,请注意上面评论的"否则肯定使用这一部分",以及我的答案的第一句话.)在这种特殊情况下,可能更好的解决方案(即这个是*不是*更普遍的一个,所以我说最好指出它的局限性,以免导致没有经验的开发人员在不考虑这些限制的情况下使用它,也许是在那些真正重要的情况下. (2认同)

sku*_*uro 5

关于什么:

(defn filter-relatives [relatives ordered-filters] 
    (first (filter identity (map relatives ordered-filters))))
Run Code Online (Sandbox Code Playgroud)

样品运行:

user=> (filter-relatives {:a 1 :b 2 :c 3} [:z :b :a])                                                               
2
Run Code Online (Sandbox Code Playgroud)


Mic*_*zyk 5

如果nilfalse不是可能的值,其他答案都很好.如果是,你可以使用类似的东西

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

例如

(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
Run Code Online (Sandbox Code Playgroud)