我有三个类似的函数,它们过滤与键(列)值匹配的映射集合,不区分大小写。
以下是我想要删除的原始代码:
;; gets a collection filtered by a column, exact match
(defn get-collection-by-equals [collection-name column-name column-value]
(filter #(= (string/lower-case (column-name %)) (string/lower-case column-value)) (cached-get-collection collection-name)))
;; gets a collection filtered by a column, with partial match, case-insensitive
(defn get-collection-by-like [collection-name column-name column-value]
(filter #(string/includes? (string/lower-case (column-name %)) (string/lower-case column-value)) (cached-get-collection collection-name)))
;; gets a collection filtered by a column, which starts with given value, case-insensitive
(defn get-collection-by-starts-with [collection-name column-name column-value]
(filter #(string/starts-with? (string/lower-case (column-name %)) (string/lower-case column-value)) (cached-get-collection collection-name)))你可以看到代码有多相似,我只是在每种情况下使用了不同的匹配策略,=,includes?和starts-with?。
我的第一次尝试是这样的:
;; returns a function which does a case-insensitive match between given column and value for the given map
(defn matching-fn [match-fn column-name column-value]
(fn [map] (match-fn (string/lower-case (column-name map)) (string/lower-case column-value))))
;; gets a collection filtered by a column, exact match
(defn get-collection-by-equals [collection-name column-name column-value]
(filter #((matching-fn = column-name column-value) %) (cached-get-collection collection-name)))
;; gets a collection filtered by a column, with partial match, case-insensitive
(defn get-collection-by-like [collection-name column-name column-value]
(filter #((matching-fn string/includes? column-name column-value) %) (cached-get-collection collection-name)))
;; gets a collection filtered by a column, which starts with given value, case-insensitive
(defn get-collection-by-starts-with [collection-name column-name column-value]
(filter #((matching-fn string/starts-with? column-name column-value) %) (cached-get-collection collection-name)))我不喜欢这个解决方案的可读性,我突然想到我可以只传递匹配的函数,而不是让一个函数返回一个函数,我想出了这个:
;; gets a collection filtered by a column, using the given function, case-insensitive
(defn get-collection-by-filter [collection-name filter-fn column-name column-value]
(filter #(filter-fn (string/lower-case (column-name %)) (string/lower-case column-value)) (cached-get-collection collection-name)))
;; gets a collection filtered by a column, exact match, case-insensitive
(defn get-collection-by-equals [collection-name column-name column-value]
(get-collection-by collection-name = column-name column-value))
;; gets a collection filtered by a column, with partial match, case-insensitive
(defn get-collection-by-like [collection-name column-name column-value]
(get-collection-by collection-name string/includes? column-name column-value))
;; gets a collection filtered by a column, which starts with given value, case-insensitive
(defn get-collection-by-starts-with [collection-name column-name column-value]
(get-collection-by collection-name string/starts-with? column-name column-value))这是惯用的Clojure吗,还有其他(更好的)解决方案吗?
使用宏似乎有点过头了。
发布于 2017-03-31 00:16:50
像许多OO模式一样,在函数式语言中,整个模式归结为“使用带参数的函数”。提取除更改为新函数的一小部分之外的所有内容,并将更改的部分作为该函数的参数。
(defn collection-comparator [cmp]
(fn [collection-name column-name column-value]
(let [lower-value (string/lower-case column-value)]
(filter #(cmp (string/lower-case (column-name %))
lower-value)
(cached-get-collection collection-name)))))
(def get-collection-by-equals (collection-comparator =))
(def get-collection-by-like (collection-comparator string/includes?))
(def get-collection-by-starts-with (collection-comparator string/starts-with?))发布于 2017-03-31 05:08:21
我只使用您的get-collection-by-filter,不再包装它-为什么要为参数可能采用的每个值创建一个新函数?
旁白:只需将描述设置为文档字符串,并将其格式化:
(defn get-collection-by-filter
"gets a collection filtered by a column, using the given function,
case-insensitive"
[collection-name filter-fn column-name column-value]
(filter #(filter-fn (string/lower-case (column-name %))
(string/lower-case column-value))
(cached-get-collection collection-name)))https://stackoverflow.com/questions/43121743
复制相似问题