通过键选择矢量中的地图的惯用法

时间:2015-05-20 22:32:24

标签: clojure clojurescript

假设我有这个地图矢量:

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

我希望选择地图:id 18347125,我该怎么做?

我已经尝试了

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

这感觉有点难看,并返回一个长度为1的序列,我想只返回地图。

4 个答案:

答案 0 :(得分:8)

恕我直言,有几种方法可以解决你的问题,而绝对惯用的方式就是品味。这是我的解决方案,我只是将“:id1834715”的地图翻译成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集作为谓词函数可以得到简洁的习语。

答案 1 :(得分:1)

我不确定这是否是最简单的写作方式,但我认为这更清楚你的意图:

(->> maps
     (filter #(= (:id %) id))
     first)

答案 2 :(得分:1)

这并不能完全按照你的要求行事,但可能仍然有用:

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旨在处理分组(即具有相同密钥的多个项目):

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}]}

答案 3 :(得分:0)

如果您不仅需要查询一次,而且需要多次查询具有特定ID的地图,我建议您的数据类型与您的用例相匹配,即将矢量更改为地图:

(def maps-by-id (zipmap (map :id maps) maps))

所以现在你的ID是这张新地图中的关键词:

user=> (maps-by-id 18347125)
{:title "Title1", :id 18347125}