ClojureDocs

Nav

Namespaces

index

clojure.set

Available since 1.0
  • (index xrel ks)
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.
3 Examples
(use '[clojure.set :only (index)])

;; 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 weigh 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

; index returns a map.  The keys are maps themselves, where {:weight 756} 
; and {:weight 1000} are taken from the maps in the weights set.  
; The values in the map returned by index are sets that contain map 
; entries from the above weights set.
user=> by-weight
{{:weight 756}  #{{:name jake, :weight 756}}, 
 {:weight 1000} #{{:name shyq, :weight 1000} 
                  {:name betsy, :weight 1000}}}

; To better visualize the by-weight map that is returned by index, 
; you can query it using get, using {:weight 756} as the key.  This 
; will return all the maps (animals) that contain a weight of 756.  
; In this case, there is only one result, which is a set containing 
; a single map. 
user=> (get by-weight {:weight 756})
#{{:name jake, :weight 756}}

; To see that there are two animals with a weight of 1000, you can 
; query by-weight with the key {:weight 1000}.  This returns a set 
; containing two maps.
user=> (get by-weight {:weight 1000})
#{{:name shyq, :weight 1000} {:name betsy :weight 1000}}

; You can verify by using count
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)
;; You can do a join using 'index'
(require '[clojure.set :as s]
         '[clojure.core.reducers :as r])
                 
(def ds1 [{:id 1 :name "name1"}
          {:id 2 :name "name2"}
          {:id 3 :name "name3"}])
          
(def ds2 [{:id 2 :address "addr2"}
          {:id 3 :address "addr3"}
          {:id 4 :address "addr4"}])

(into () (r/map #(r/reduce merge %) (vals (s/index (s/union ds2 ds1) [:id]))))
;; ({:id 1, :name "name1"}
;;  {:id 4, :address "addr4"}
;;  {:id 3, :name "name3", :address "addr3"}
;;  {:id 2, :address "addr2", :name "name2"})
;; use index to query a data set

(def data [{:gender "male",   :age-group "child",  :origin "Germany", :prename "Hans"}
	   {:gender "male",   :age-group "adult",  :origin "France",  :prename "Jacques"}
	   {:gender "male",   :age-group "senior", :origin "Estonia", :prename "Rasmus"}
	   {:gender "male",   :age-group "adult",  :origin "Poland",  :prename "Jakub"}
	   {:gender "male",   :age-group "senior", :origin "Germany", :prename "Uwe"}
	   {:gender "female", :age-group "adult",  :origin "France",  :prename "Amélie"}
	   {:gender "female", :age-group "child",  :origin "Estonia", :prename "Sofia"}
	   {:gender "female", :age-group "child",  :origin "Germany", :prename "Emma"}
	   {:gender "female", :age-group "child",  :origin "Estonia", :prename "Alisa"}
	   {:gender "female", :age-group "senior", :origin "Poland",  :prename "Anna"}])

(def the-index (clojure.set/index data [:gender :origin]))

;; find all men originating from Germany:

(get the-index {:gender "male" :origin "Germany"})

;; =>

#{{:gender "male", :age-group "child", :origin "Germany", :prename "Hans"}
  {:gender "male", :age-group "senior", :origin "Germany", :prename "Uwe"}}
See Also

keyval => key val Returns a new hash map with supplied mappings. If any keys are equal, they ar...

Added by boxie

Returns the value mapped to key, not-found or nil if key not present in associative collection, se...

Added by boxie
0 Notes
No notes for index