问题
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