在Clojure中开发一个函数来检查:maxlength和:minlength的输入是否长度为1-3个字符,相关列中的文本是否在min和max范围内。有更清洁的方法吗?如果建议使用更有效的方法,尤其是if表单,我将不胜感激。
(defn range-text-length
"input = {:col val :minlength minlength :maxlength maxlength}
Expects 3 parameter key/value combinations:
:col The column containing the text value
:maxlength integer value greater than zero up to 3 characters long
Catch any rows where the column contains text that is shorter than the Minimum Length or longer than the Maximum Length"
[row input]
(let [{:keys [col minlength maxlength ]} input
minlength-count (count (str minlength))
maxlength-count (count (str maxlength))
max (read-string (str maxlength))
min (read-string (str minlength))]
(if (and (and (> maxlength-count 0) (<= maxlength-count 3) (number? max) (> max 0))
(and (> minlength-count 0)(<= minlength-count 3)(number? min)(> min 0)))
(and (>= (count (get row col)) min) (<= (count (get row col)) max))
(throw (Exception. "length must be a positive integer value with no more than 3 digits.")))))
我这样称呼函数:
(catch-out-of-range-text-length ["weert" "sertt" "qwertyuiopasdfg" "asert"] {:col 2 :minlength 2 :maxlength 15})
答案 0 :(得分:2)
我认为以下内容与您的相同:
(defn range-text-length [row input]
(let [in-range? (fn [n] (< 0 n 1000))
{:keys [col minlength maxlength ]} input
]
(if (every? in-range? [minlength maxlength])
(<= minlength (count (row col)) maxlength)
(throw (Exception. "length must be a positive integer with no more than 3 digits.")))))
答案 1 :(得分:0)
首先关闭:嵌套and
是多余的。由于代码无法区分条件的哪一部分是错误的,因此对and
的嵌套调用没有影响,而不是将所有子句放在同一个and
中。
接下来,<
,<=
,>
和>=
都会获取可变数量的参数,并且通过一些重构,您可以组合共享一个术语
最后,您可以直接测试pos?
是否为正数,而不是测试是否大于0。
(defn range-text-length
"input = {:col val :minlength minlength :maxlength maxlength}
Expects 3 parameter key/value combinations:
:col The column containing the text value
:maxlength integer value greater than zero up to 3 characters long
Catch any rows where the column contains text that is shorter than the Minimum Length or longer than the Maximum Length"
[row input]
(let [{:keys [col minlength maxlength ]} input
minlength-count (count (str minlength))
maxlength-count (count (str maxlength))
max (read-string (str maxlength))
min (read-string (str minlength))]
(if (and (> 4 maxlength-count 0)
(number? max)
(pos? max)
(> 4 minlength-count 0)
(number? min)
(pos? min))
(>= max (count (get row col)) min)
(throw (Exception. "length must be a positive integer value with no more than 3 digits.")))))
答案 2 :(得分:0)
我看到你已经将@noisesmith标记为答案。虽然这种情况正在发生,但我正在玩弄并产生以下内容:
(defn range-text-length
[row {:keys [col minlength maxlength] :as input}]
(if-let [x (and (and (pos? minlength) (< minlength 1000))
(and (pos? maxlength) (< maxlength 1000))
(and (>= (count (get row col)) minlength)
(<= (count (get row col)) maxlength)))]
true
(throw (Exception. "length must be a positive integer value with no more than 3 digits."))))
尽管我and
的可变性能力因为可读性而分开。
编辑:远离if-let
:
(defn range-text-length
[row {:keys [col minlength maxlength] :as input}]
(or (and (and (pos? minlength) (< minlength 1000))
(and (pos? maxlength) (< maxlength 1000))
(and (>= (count (get row col)) minlength)
(<= (count (get row col)) maxlength)))
(throw (Exception. "length must be a positive integer value with no more than 3 digits."))))
答案 3 :(得分:-1)
if
子句整理和前提条件,用于避免使用假定的前提条件污染函数的真实目的。一些额外的examples
(defn range-text-length
"input = {:col val :minlength minlength :maxlength maxlength}
Expects 3 parameter key/value combinations:
:col The column containing the text value
:maxlength integer value greater than zero up to 3 characters long
Catch any rows where the column contains text that is shorter than the Minimum Length or longer than the Maximum Length"
[row input]
{: pre [(let [{:keys [col minlength maxlength ]} input
minlength-count (count (str minlength))
maxlength-count (count (str maxlength))
max (read-string (str maxlength))
min (read-string (str minlength))
crc (count (get row col))]
(not (and (pos? maxlength-count)
(pos? minlength-count)
(pos? max)
(pos? min)
(<= maxlength-count 3)
(<= minlength-count 3)
(>= crc min)
(<= crc max))))]}
(do (println "do my stuff with satisfied preconditions")))