请在 2024 年Clojure状态调查中分享您的想法!

欢迎!请参阅关于页面了解更多此工作的信息。

0
Clojure by

我有一些数据,可以进行简单的过滤操作

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

效果很好。

我还有另一个数据源,post,我想将一个字段转换为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:1)的def处有语法错误。def的参数太多。
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`仅使用谓词的真值,因此您可以从最后一个匿名函数中移除“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))
...