给定Clojure中的一系列映射,如何过滤键的值>(某个值)?

mon*_*962 4 dictionary clojure filter sequence

我有一系列Clojure地图,看起来像这样:

({:date "2000-01-01" :value 123} 
 {:date "2000-01-02" :value 487} 
 ... 
 {:date "2014-05-01" :value 17})
Run Code Online (Sandbox Code Playgroud)

我想构建一个函数,它将返回一个类似结构的映射序列,但只包含那些映射:例如"2005-11-14"和"2007-08-03"之间的日期值.

在他们目前的YYYY-MM-DD形式中,日期是可比较的,因此(compare "2000-01-02" "2001-03-04")按预期工作.但是,我无法弄清楚如何从序列中提取:date值并进行比较.

我已经做到了,(filter #(> 0 (compare (:date %)) "2099-12-09") data)但无法进一步.救命!

ymo*_*nad 7

在Clojure中,诸如向量,集合和映射之类的数据结构可以用作函数.这意味着如果x是地图,您可以通过类似的方式获得价值(x :date).因此,以下代码将完成这项工作.

(def data '({:date "2005-11-13", :value 0}
         {:date "2005-11-15", :value 1}
         {:date "2007-08-02", :value 2}
         {:date "2007-08-04", :value 3}))
(print (filter
         #(and
               (> (compare (% :date) "2005-11-14") 0)
               (< (compare (% :date) "2007-08-03") 0))
         data))
Run Code Online (Sandbox Code Playgroud)

输出将是

({:date 2005-11-15, :value 1} {:date 2007-08-02, :value 2})
Run Code Online (Sandbox Code Playgroud)

编辑:以下代码略好一些,因为它每次迭代都会从map获取一次.

 (print (filter
         #(let [x (% :date)]
           (and
              (> (compare x "2005-11-14") 0)
              (< (compare x "2007-08-03") 0)))
         data))
Run Code Online (Sandbox Code Playgroud)