请在 2024 Clojure 调查问卷! 中分享您的想法。

欢迎!有关如何使用本服务的更多信息,请参阅关于 页面。

+1
语法和读取器

我对这个问题深有同感。有一个函数,根据参数重复执行相同的指令,除了一个元素(在这种情况下是一个过滤器)。我该如何解决这个问题呢?

(defn get-threads
  "Get all urls threads"
    ([]
     (let [comments (distinct (map (fn [comment] { :thread (:thread comment) }) @db))]
   comments))
    ([search]
     (let [comments (distinct (map (fn [comment] { :thread (:thread comment) }) @db))]
   (filter (fn [comment] (s/includes? (s/upper-case (:thread comment)) (s/upper-case search))) comments))))

2 答案

+1

一个方法是将公共代码提取出来。

(defn get-comments []
  (distinct (map (fn [comment] { :thread (:thread comment) }) 
    @db))

(defn get-threads
  "Get all urls threads"
    ([] (get-comments))
    ([search]
      (->> (get-comments)
           (filter (fn [comment]
                     (s/includes? (s/upper-case (:thread comment)) 
                                             (s/upper-case search))))

由于函数定义和组合都很简单,通常会有许多小函数组合成更复杂的函数。

非常感谢
+1

在这个特定情况下,我可能将 searchnil 值视为在 filter 调用中始终匹配。

(filter (fn [comment] (or (nil? search)
                          (s/includes? (s/upper-case (:thread comment))
                                       (s/upper-case search))))
        comments)

然后,您可以只让 0 个参数版本的函数调用 1 个参数版本的,使用 nil

(defn get-threads
  "Get all urls threads"
  ([] (get-threads nil))
  ([search]
   (let [comments ...]
     (filter ... comments))))

这里另一个选项是使用 cond->>

(cond->> (distinct (map (fn [comment] ...)  @db))
  search
  (filter (fn [comment] (s/includes? ...)))

这将仅在 search 不为 nil 时将注释传递给 filter 调用,否则它将返回所有未过滤的注释。

通常,如果有多个参数(由于可选参数),我会为可选参数选择一个“空”值,并让较低的参数调用完整参数,传递这些“空”值,例如零、nil、空列表等。然后完整参数版本将条件性地处理这些“空”值。

非常有趣,我没想到以这种方式解决问题。非常感谢。
...