fork download
  1. (defrecord IndexedSet [elements indices])
  2.  
  3. (def empty-indexed-set (->IndexedSet #{} {}))
  4.  
  5. (defn add-index [iset name key]
  6. (assoc-in iset [:indices name]
  7. {:key key
  8. :values (into {} (map (fn [x] [(key x) x])
  9. (:elements iset)))}))
  10.  
  11. (defn add [iset value]
  12. (reduce (fn [iset [name {key :key}]]
  13. (update-in iset [:indices name :values]
  14. assoc (key value) value))
  15. (update iset :elements conj value)
  16. (:indices iset)))
  17.  
  18. (defn lookup [iset name value]
  19. (get-in iset [:indices name :values value]))
  20.  
  21. ;; USAGE
  22.  
  23. (defrecord User [id name email-address])
  24.  
  25. (def elems
  26. (-> empty-indexed-set
  27. (add-index :id :id)
  28. (add-index :email-address :email-address)
  29. (add (->User 1 "elyse" "rightfold@gmail.com"))
  30. (add (->User 2 "foo" "foo@bar.com"))
  31. (add (->User 3 "bar" "fool@barl.com"))))
  32. (-> elems (lookup :email-address "rightfold@gmail.com") (println))
  33. (-> elems (lookup :id 3) (println))
Success #stdin #stdout 1.95s 335552KB
stdin
Standard input is empty
stdout
#user.User{:id 1, :name elyse, :email-address rightfold@gmail.com}
#user.User{:id 3, :name bar, :email-address fool@barl.com}