鉴于下面的多种方法 -
(defmulti group-data :group-by)
(defmethod group-data :day
[kv]
(->> kv :data (group-by
(fn [kv]
(let [date (:time kv)]
(str
(month date) "-" (day date) "-" (year date)))))))
(defmethod group-data :month
[kv]
(->> kv :data (group-by
(fn [kv]
(let [date (:time kv)]
(str
(month date) "-" (year date)))))))
(defmethod group-data :year
[kv]
(->> kv :data (group-by
(fn [kv]
(let [date (:time kv)]
(year date))))))
在所有三种多方法中,唯一的区别是字符串函数。如何创建一个更高阶的函数,它只需要用不同的表达式来创建字符串?
还有减少重复代码的更好的想法吗?
答案 0 :(得分:4)
有时您不需要多方法:
(def dmap {:day #(str (month %) "-" (day %) "-" (year %))
:month #(str (month %) "-" (year %))
:year #(year %)})
(defn group-data [kv]
(->> kv :data (group-by
(fn [kv]
(let [date (:time kv)]
((dmap (:group-by kv)) date))))))
答案 1 :(得分:3)
最简单的答案是定义一个包含所有共享逻辑的函数,该函数接收另一个用于填充变化的“漏洞”的函数:
(defn helper [kv time-fn]
(->> kv :data (group-by
(fn [kv]
(let [date (:time kv)]
(timefn data))))))
(defmulti group-data :group-by)
(defmethod group-data :day
[kv]
(helper kv (fn [date]
(str (month date) "-" (day date) "-" (year date)))))
(defmethod group-data :month
[kv]
(helper kv
(fn [date]
(str (month date) "-" (year date)))))
(defmethod group-data :year
[kv]
(helper kv year))
答案 2 :(得分:2)
答案 3 :(得分:1)
已经有3个答案而且没有提到宏:)我知道有更明显的理由喜欢更高阶的函数,但宏至少应该得到一个答案,所以这里是:
(defmacro group-by-template [date-symbol expression coll]
`(group-by
(fn [kv#]
(let [~date-symbol (:time kv#)]
~expression)) ~coll))
(defmulti group-data :group-by)
(defmethod group-data :day
[kv]
(->> kv :data (group-by-template date (str (month date) "-" (day date) "-" (year date)))))
(defmethod group-data :month
[kv]
(->> kv :data (group-by-template date (str (month date) "-" (year date)))))
(defmethod group-data :year
[kv]
(->> kv :data (group-by-template date (year date))))