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、空列表等。然后完整参数版本将根据需要条件性地处理这些“空”值。

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