按地图矢量中的键值查找上一项

时间:2017-05-26 20:39:36

标签: clojure clojurescript

我有一个这样的地图矢量:

[{:id 2 :val "v1"} {:id 5 :val "v2"} {:id 10 :val "v3"}]

现在我想找到所选id之前的元素。 例如:当提供id = 10时,我希望收到:

{:id 5 :val "v2"}

当选择id = 2时,则返回nil。

我是clojurescript编程的新手,想不出这个问题的简单解决方案......请帮助:)

2 个答案:

答案 0 :(得分:3)

您可以使用partition配对相邻的地图,然后按ID搜索第二个地图上的匹配项:

(def ms [{:id 2 :val "v1"} {:id 5 :val "v2"} {:id 10 :val "v3"}])
(ffirst (filter #(= 10 (:id (second %))) (partition 2 1 ms)))

答案 1 :(得分:1)

接受的答案中的

(partition 2 1 data)是一个选项,但这里有两个基于"滞后"的替代方案。序列

这个首先构造查找表(映射下一个id到每个项目),如果需要进行许多查找,这应该更高效。你甚至可以轻松map。但这种方法要求ID是唯一的。

(let [data [{:id 2 :val "v1"} {:id 5 :val "v2"} {:id 10 :val "v3"}]
      ids  (zipmap (map :id (rest data)) data)]
  [(ids 10)
   ids])
; [{:id 5, :val "v2"}
;  {5 {:id 2, :val "v1"}, 10 {:id 5, :val "v2"}}]

第二个生成一系列匹配文档,如果可能有多个匹配文档,则这是必需的:

(let [data     [{:id 2 :val "v1"} {:id 5 :val "v2"} {:id 10 :val "v3"}]
      next-ids (->> data rest (map :id))]
  (->>
    (map (fn [item next-id] (if (= 10 next-id) item))
      data next-ids)
    (filter some?)
    first))
; {:id 5, :val "v2"}

您使用partition获得了类似的代码,但您使用的是#(...)而不是(fn [first-item second-item] (= 10 (:id second-item)))thread。确实ffirst在这种方法中非常方便。