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

欢迎!请查看关于页面,了解更多关于此运作方式的信息。

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 并与今天进行比较。

但是它无法编译

Syntax error compiling def at (clojure_json_test/core.clj:46:1). Too many arguments to def
Too many arguments to def

顺便说一句,我使用的是

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

1 答案

0

selected
 
最佳答案

您可以在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 %)今天) (获取带有日期的帖子))
...