2024 年 Clojure 状态调查!分享您的想法。

欢迎!请参阅关于页面获取更多有关操作的信息。

0
Clojure

我有一些数据,可以对它们进行简单的过滤。

(defn get-posts-body 
  []
  (:body @(client/get posts-url api-options)))

(defn get-books
  []
  (parse-string (get-books-body) true))

(defn get-non-fiction-books
  []
  (filter #(if (= "non-fiction" (:category %)) %) (get-books)))

这很好用。

我还有另一个数据源,帖子,我想要将一个字段转换成 DateTime 类型并进行比较。但它不起作用

(defonce today (.withTimeAtStartOfDay (t/now)))

(defn get-posts-body 
  []
  (:body @(client/get posts-url api-options)))

(defn get-posts
  []
  (parse-string (get-posts-body) true))

(def get-posts-viewed-today
  []
  (filter #(if (>= (f/parse :date-time (:last_viewed_at %)) today) %) (get-posts)))

我想获取所有具有 last_viewed_at DateTime ≥ 今天的 Maps。

我正在尝试将 String last_viewed_at 转换为 DateTime 并与今天进行比较。

但是它不会编译

在 (clojure_json_test/core.clj:46:1) 编译 def 时出现语法错误。参数太多
def

顺便提一下,我正在使用

(:require [clj-time.core :as t]
          [clj-time.format :as f]
          ;; ... )

1 个答案

0

选中Answer
 
最佳答案

您可以在https://clojure.github.io/clojure/的API参考中找到 def 和 defn 。您可以使用(def x (fn [a b c] ...))设置一个函数,但 defn 更简单。

有一些转换+过滤的惯用方法,特别是如果最终结果应该是从转换的值中选择时,尤其有用。一个惯用方法是分离这两个过程,如下

(->> some-collection (map ...) (filter ...))

这的优点是灵活性强 - 有很多函数可以操作序列。另一种技术是使用 (keep ...),这是一种结合映射和过滤的特殊情况。map、filter 和 keep 都在相同的 API 参考页面上。

谢谢!问题解决了。我采用了你的建议,将转换拆分到另一个函数中。指定joda格式化器时,我也有语法错误。我没有意识到joda有一个我可以使用的after?函数。

    (defn get-posts-with-dates
      []
      (map #(merge % {:last_viewed_at (f/parse (f/formatters :date-time-no-ms) (:last_viewed_at %))}) (get-posts)))

    (defn get-posts-viewed-today
      []
      (filter #(if (t/after? (:last_viewed_at %) today) %) (get-posts-with-dates)))

我不确定这是Clojure中使用的一种最标准的做法,但它有效。
`filter`只需要判断谓词的真假,所以你可以从那个匿名函数中移除"if"层。`t/after?`的返回值将足够好。

编辑
有谁知道这会是什么样子吗?我尝试减少了几层,但编译器报错。这是我第一次使用filter,有点困惑。

这些方法都没用

    (filter (t/after? (:last_viewed_at %) today) %) (get-posts-with-dates)

    (filter t/after? (:last_viewed_at %) today) % (get-posts-with-dates)
不用管了,我明白了

    (filter #(t/after? (:last_viewed_at %) today) (get-posts-with-dates))
...