通过键 select 矢量地图的惯用方式
Idiomatic way to select a map in vector by a key
假设我有这个地图向量:
[{:title "Title1" :id 18347125}
{:title "Title2" :id 18347123}
{:title "Title3" :id 18341121}]
我想 select :id 18347125 的地图,我该怎么做?
我试过了
(for [map maps
:when (= (:id map) id)]
map)
感觉有点丑 return 是一个长度为 1 的序列,我只想 return 映射。
我不确定这是不是最简单的写法,但我认为这样更能表达你的意图:
(->> maps
(filter #(= (:id %) id))
first)
恕我直言,有几种方法可以解决您的问题,绝对惯用的方法是品味领域。这是我的解决方案,我只是将 "to select maps whose :id
is 1834715
" 翻译成 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})
:id
关键字是一个在传递给它的集合中查找自身的函数。集合 #{18347125}
也是一个函数,用于测试传递给它的值是否等于 18347125
。使用 Clojure 集作为谓词函数允许简洁的习惯用法。
如果您不仅需要查询一次,而且需要多次查询具有特定 ID 的地图,我建议您使数据类型与您的用例相匹配,即将向量更改为地图:
(def maps-by-id (zipmap (map :id maps) maps))
所以现在您的 ID 是这个新地图中的键:
user=> (maps-by-id 18347125)
{:title "Title1", :id 18347125}
这并不能完全满足您的要求,但可能仍然有用:
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}]}
现在您可以简单地通过 id 查找地图。详细了解 group-by on clojuredocs,这是一个非常有用的功能。
请注意,它将地图放在向量中。这是因为 group-by 被设计用来处理 grouping(即具有相同 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}]}
假设我有这个地图向量:
[{:title "Title1" :id 18347125}
{:title "Title2" :id 18347123}
{:title "Title3" :id 18341121}]
我想 select :id 18347125 的地图,我该怎么做?
我试过了
(for [map maps
:when (= (:id map) id)]
map)
感觉有点丑 return 是一个长度为 1 的序列,我只想 return 映射。
我不确定这是不是最简单的写法,但我认为这样更能表达你的意图:
(->> maps
(filter #(= (:id %) id))
first)
恕我直言,有几种方法可以解决您的问题,绝对惯用的方法是品味领域。这是我的解决方案,我只是将 "to select maps whose :id
is 1834715
" 翻译成 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})
:id
关键字是一个在传递给它的集合中查找自身的函数。集合 #{18347125}
也是一个函数,用于测试传递给它的值是否等于 18347125
。使用 Clojure 集作为谓词函数允许简洁的习惯用法。
如果您不仅需要查询一次,而且需要多次查询具有特定 ID 的地图,我建议您使数据类型与您的用例相匹配,即将向量更改为地图:
(def maps-by-id (zipmap (map :id maps) maps))
所以现在您的 ID 是这个新地图中的键:
user=> (maps-by-id 18347125)
{:title "Title1", :id 18347125}
这并不能完全满足您的要求,但可能仍然有用:
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}]}
现在您可以简单地通过 id 查找地图。详细了解 group-by on clojuredocs,这是一个非常有用的功能。
请注意,它将地图放在向量中。这是因为 group-by 被设计用来处理 grouping(即具有相同 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}]}