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

欢迎!请查看关于页面以了解有关如何工作的更多信息。

0

我有一些数据,能够对它们进行简单的筛选

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

我想获取所有最后阅读时间DateTime >= 今天的Map

我试图将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
 
最佳答案

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

有一些转换-expressing-filtering惯用方法,特别是如果最终结果应该是从转换后的值中选择时。一个惯用方法是分离这两个过程,大致如下

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