Returns a map of the distinct values of ks in the xrel mapped to a
set of the maps in xrel with the corresponding values of ks.
;; Suppose you have a set of descriptions of the weights of animals:
user=> (def weights #{ {:name 'betsy :weight 1000}
{:name 'jake :weight 756}
{:name 'shyq :weight 1000} })
;; You want the names of all the animals that weight 1000. One way to do
;; that uses `index`. First, you can group the set elements (the maps) so
;; that those with the same weights are in the same group.
user=> (def by-weight (index weights [:weight]))
#'user/by-weight
user=> by-weight
{{:weight 756} #{{:name jake, :weight 756}},
{:weight 1000} #{{:name shyq, :weight 1000}
{:name betsy, :weight 1000}}}
;; That structure's a little complicated, so let's first use it in simple
;; ways. To get all the maps that describe animals that weigh 756, you'd
;; do this:
user=> (get by-weight {:weight 756})
#{{:name jake, :weight 756}}
;; That's a set containing a single element. To confirm that there are two
;; animals with weight 1000, this:
user=> (count (get by-weight {:weight 1000}))
2
;; To get the names of those two animals we can map a name-extracting function
;; over the set of two maps. Since a keyword in a map is also a function that
;; returns its corresponding value, we can just use `:name` as our function:
user=> (map :name (get by-weight {:weight 1000}))
(shyq betsy)
(defn index
"Returns a map of the distinct values of ks in the xrel mapped to a
set of the maps in xrel with the corresponding values of ks."
{:added "1.0"}
[xrel ks]
(reduce
(fn [m x]
(let [ik (select-keys x ks)]
(assoc m ik (conj (get m ik #{}) x))))
{} xrel))
Comments top
No comments for index. Log in to add a comment.