请在 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 >=今天的 Map。

我正在尝试将 String 类型的 last_viewed_at 转换为 DateTime 并与之比较。

但它无法编译。

在文件 clojure_json_test/core.clj 第 46 行编译 def 时出现语法错误。Too
def 有太多参数。

顺便说一下,我正在使用

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

1 答案

0

选中
 
最佳答案

您可以在 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)
by
没关系,我想出来了

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