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)))

这工作得很好。

我还有一个数据源,文章,我想将一个字段转换为日期时间类型并进行比较。尽管它不起作用

(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 日期时间 >= 当天的 Map。

我在尝试将 String last_viewed_at 转换为日期时间并与今天进行比较。

但它无法编译

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
by
selected by
 
最佳答案

您可以在 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,有点困惑。

这些都没能工作



    (filter (t/after? (:last_viewed_at %) today) %) (get-posts-with-dates)
不用在意,我已经想明白了

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