问题
For this nested map called "tables",
(def tables
{:tableA {:occupied false :party nil}
:tableB {:occupied true :party nil}
:tableC {:occupied false :party nil}})
how do I filter and get back the keys where :occupied = false ?
correct result should be (:tableA :tableC)
can I do this with "filter" HOF? Should I be using a list comprehension?
回答1:
You could do it pretty easily with keep:
(keep (fn [[k v]] (if-not (:occupied v) k)) tables)
However, as you observed, using for is often a good solution whenever you're mapping / filtering sequences, especially if you're dealing with nested sequences.
(for [[k v] tables :when (not (:occupied v))] k)
I usually prefer using for, especially when I want to use destructuring on the target items. In this case, destructuring is nice for binding the key/value pair with [k v].
回答2:
I'm not sure what your use case is, but can I suggest structuring your data as a set of maps? Sets have certain properties that allow you to query them using relational algebra similar to the way you query tables in SQL. The clojure.set/select function is similar to a WHERE in SQL.
(use 'clojure.set)
(def tables
#{{:table "A" :occupied false :party nil}
{:table "B" :occupied true :party nil}
{:table "C" :occupied false :party nil}})
(select #(= false (:occupied %)) tables)
Hope this helps!
来源:https://stackoverflow.com/questions/19886035/clojure-filter-nested-map-to-return-keys-based-on-inner-map-values