clojure: search in a map with multiple keys

85 views Asked by At

I have a map called myData. It has 2 keys: :user_id and :name. I want to search it by the 2 keys.

{{:user-id 1, :name "abc"} [{:user-id 1, :name "abc", :uri "/"}],
 {:user-id 2, :name "bcd"} [{:user-id 2, :name "bcd", :uri "/foo"}],
 {:user-id 1, :name "cde"} [{:user-id 1, :name "cde", :uri "/account"}]}

I have tried: (get-in mydata [:user-id 1 :name "abc"]) and (get-in mydata [1 "abc"]). Neither of them works. What's the correct way to retrieve the data?

2

There are 2 answers

0
bfabry On BEST ANSWER

You have a map with keys that are maps that look like {:user-id 1, :name "abc"}, so in order to get the values associated with those keys you should pass a map that looks like that into get.

(get
  {{:user-id 1, :name "abc"} [{:user-id 1, :name "abc", :uri "/"}],
   {:user-id 2, :name "bcd"} [{:user-id 2, :name "bcd", :uri "/foo"}],
   {:user-id 1, :name "cde"} [{:user-id 1, :name "cde", :uri "/account"}]}
  {:user-id 1 :name "abc"})
0
Carcigenicate On

The other answer is correct.

I would maybe reconsider how you have things set up though. Having a whole map as a key is going to make your life harder in many cases since you'll need to have access to the whole map to do a lookup. If you have the whole maps on hand, then it may be fine for your case here.

I'd maybe "normalize" how you have the data stored though for easier lookups and to reduce redundancy:

(def m {1 {"abc" "/", 
           "cde" "/account"}
        2 {"bcd" "/foo"}})

(get-in m [1 "cde"])  ; "/account"
(get-in m [2 "bcd"])  ; "/foo"

Now you don't have repeated data, and you don't need access to all the data at once to do a lookup.