Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Idiomatic way to select a map in vector by a key

Suppose I have this vector of maps:

[{:title "Title1" :id 18347125}
 {:title "Title2" :id 18347123}
 {:title "Title3" :id 18341121}]

And I wish to select the map with :id 18347125, how would I do this?

I've tried

(for [map maps
      :when (= (:id map) id)]
    map)

This feels a bit ugly and returns a sequence of length one, and I want to return just the map.

like image 307
Pete Avatar asked Dec 15 '22 14:12

Pete


2 Answers

IMHO, there are several ways to solve your problem, and the definitely idiomatic way is in the realm of taste. This is my solution where I simply translated "to select maps whose :id is 1834715" into Clojure.

user> (def xs [{:title "Title1" :id 18347125}
               {:title "Title2" :id 18347123}
               {:title "Title3" :id 18341121}])
#'user/xs

user> (filter (comp #{18347125} :id) xs)
({:title "Title1", :id 18347125})

The :id keyword is a function that looks up itself in a collection passed to it. The set #{18347125} is also a function that tests if a value passed to it equals 18347125. Using a Clojure set as a predicate function allows for a succinct idiom.

like image 199
tnoda Avatar answered Jan 28 '23 14:01

tnoda


I'm not sure if it's the simplest way to write it, but I think this is more clear about your intentions:

(->> maps
     (filter #(= (:id %) id))
     first)
like image 20
Anthony R. Avatar answered Jan 28 '23 15:01

Anthony R.