Clojure get nested map value

試著忘記壹切 提交于 2020-04-28 04:16:05

问题


So I'm used to having a nested array or map of settings in my applications. I tried setting one up in Clojure like this:

(def gridSettings
  {:width 50
   :height 50
   :ground {:variations 25}
   :water {:variations 25}
   })

And I wondered if you know of a good way of retrieving a nested value? I tried writing

(:variations (:ground gridSettings))

Which works, but it's backwords and rather cumbersome, especially if I add a few levels.


回答1:


That's what get-in does:

(get-in gridSettings [:ground :variations])

From the docstring:

clojure.core/get-in
([m ks] [m ks not-found])
  Returns the value in a nested associative structure,
  where ks is a sequence of keys. Returns nil if the key
  is not present, or the not-found value if supplied.



回答2:


You can use the thread-first macro:

(-> gridSettings :ground :variations)

I prefer -> over get-in except for two special cases:

  • When the keys are an arbitrary sequence determined at runtime.
  • When supplying a not-found value is useful.



回答3:


Apart from what other answers has mentioned (get-in and -> macro), sometimes you want to fetch multiple values from a map (nested or not), in those cases de-structuring can be really helpful

(let [{{gv :variations} :ground
       {wv :variations} :water} gridSettings]
  [gv wv]) 



回答4:


Maps are partial functions (as in not total). Thus, one can simply apply them as functions. Based on the map from the question:

(gridSettings :ground)
;=> {:variations 25}

The result is a map. So, it can be applied again, which results in a very similar (but not backwards) "syntax" as proposed in the question:

((gridSettings :ground) :variations)
;=>25 


来源:https://stackoverflow.com/questions/15639060/clojure-get-nested-map-value

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!