在Clojure中进行比较

时间:2015-07-22 12:00:47

标签: clojure

在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})

4 个答案:

答案 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")))