An idiomatic way to select a card in a vector using a key
Suppose I have this vector of mappings:
[{:title "Title1" :id 18347125}
{:title "Title2" :id 18347123}
{:title "Title3" :id 18341121}]
And I want to select a card with: id 18347125, how would I do that?
I tried
(for [map maps
:when (= (:id map) id)]
map)
This seems a little ugly and returns a sequence of length one and I only want to return the map.
source to share
IMHO, there are several ways to solve your problem, and the definitely idiomatic way is in the realm of taste. It's my decision, I just translated "to select the card, :id
which 1834715
" in 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})
A keyword :id
is a function that itself searches the collection passed to it. Set is #{18347125}
also a function that checks if a value is equal to 18347125
. Using Clojure, defined as a predicate function, allows for a concise idiom.
source to share
This is not exactly what you asked for, but it might be useful, nevertheless:
user=> (group-by :id [{:title "Title1" :id 18347125}
{:title "Title2" :id 18347123}
{:title "Title3" :id 18341121}])
{18347125 [{:title "Title1" :id 18347125}]
18347123 [{:title "Title2" :id 18347123}]
18341121 [{:title "Title3" :id 18341121}]}
Now you can just look up the map by id. Read more about group-on at clojuredocs , it's a very useful feature.
Note that it puts maps inside vectors. This is because group-by is designed to handle grouping (i.e. Multiple items with the same key):
user=> (group-by :id [{:title "Title1" :id 123}
{:title "Title2" :id 123}
{:title "Title3" :id 18341121}])
{123 [{:title "Title1" :id 123} {:title "Title2" :id 123}]
18341121 [{:title "Title3" :id 18341121}]}
source to share
If you need to query not only once, but multiple times for cards with specific IDs, I would suggest making your datatypes appropriate for your use, i.e. change vector to map:
(def maps-by-id (zipmap (map :id maps) maps))
So now your IDs are the keys on this new map of maps:
user=> (maps-by-id 18347125)
{:title "Title1", :id 18347125}
source to share