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

在这个特定情况下,我可能将搜索参数的 nil 值视为在 filter 调用中“始终匹配”

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

然后你可以直接让 0 个参数的函数调用以 nil 为参数调用 1 个参数的版本

(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 非空时将评论传递给 filter 调用,否则将返回所有未过滤的评论。

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

非常有趣,我 hadn't thought of solving it this way. 感谢您。
...