0
votes

i need to retrieve the key whose value contains a string "TRY"

:CAB "NAB/TRY/FIGHT.jar"

so in this case the output should be :CAB .

I am new to Clojure, I tried a few things like .contains etc but I could not form the exact function for the above problem.its easier in few other languages like python but I don't know how to do it in Clojure.

Is there a way to retrieve the name of the key ?

4
Do you mean: the key whose value contains the substring "try"?manandearth
yes that's what i meanN.Singh

4 Answers

2
votes

for can also filter with :when. E.g.

(for [[k v] {:FOO "TRY" :BAR "BAZ"} 
      :when (.contains v "TRY")] 
        k)
2
votes

First, using .contains is not recommended - first, you are using the internals of the underlying language (Java or JavaScript) without need, and second, it forces Clojure to do a reflection as it cannot be sure that the argument is a string.

It's better to use clojure.string/includes? instead.

Several working solutions have been already proposed here for extracting a key depending on the value, here is one more, that uses the keep function:

(require '[clojure.string :as cs])

(keep (fn [[k v]] (when (cs/includes? v "TRY") k))
      {:CAB "NAB/TRY/FIGHT.jar" :BLAH "NOWAY.jar"})  ; => (:CAB)
0
votes

The easiest way is to use the contains method from java.lang.String. I'd use that to map valid keys, and then filter to remove all nil values:

(filter some? 
        (map (fn [[k v]] (when (.contains v "TRY") k)) 
             {:CAB "NAB/TRY/FIGHT.jar" :BLAH "NOWAY.jar"}))
=> (:CAB)

If you think there is at most one such matching k/v pair in the map, then you can just call first on that to get the relevant key.

You can also use a regular expression instead of .contains, e.g.

(fn [[k v]] (when (re-find #"TRY" v) k))
0
votes

You can use some on your collection, some will operate in every value in your map a given function until the function returns a non nil value.

We're gonna use the function

(fn [[key value]] (when (.contains values "TRY") key))

when returns nil unless the condition is matched so it will work perfectly for our use case. We're using destructuring in the arguments of the function to get the key and value. When used by some, your collection will indeed be converted to a coll which will look like

'((:BAR "NAB/TRY/FIGHT.jar"))

If your map is named coll, the following code will do the trick

(some
  (fn [[key value]] (when (.contains value "TRY") key)) 
  coll)