法律上做事的方式是什么



作为一个更大程序的一部分,我正在测试一个函数,该函数将把一个类发生的一系列日子(如"MWF")转换为七个数字的列表:(1 0 1 0 1 1 0 0)。我首先把"TH"(星期四)翻译成"R",把"SU"(星期日)翻译成了"N",让事情变得简单一点。

我想出了以下代码:

(defn days-number-maker
  "Recursively compare first item in days of week with
first item in string of days. If matching, add a 1,
else add a zero to the result"
  [all-days day-string result]
  (if (empty? all-days) (reverse result)
    (if (= (first all-days) (first day-string))
      (recur (rest all-days)(rest day-string) (conj result 1))
      (recur (rest all-days) day-string (conj result 0)))))
(defn days-to-numbers
  "Change string like MTTH to (1 1 0 1 0 0 0)"
  [day-string]
  (let [days (clojure.string/replace
               (clojure.string/replace day-string #"TH" "R") #"SU" "N")]
    (days-number-maker "MTWRFSN" days (list))))

好消息是:代码有效。坏消息是:从道德纯洁的角度来说,我确信我做错了。我内心的某种东西说,"你本可以用(map…)以正确的方式来做这件事,"但我不知道如何用(map)来做。所以,我的两个问题是:

1) 有"Clojure方式"这样的东西吗?如果有,2) 如何重写代码以使其更像Clojure?

您可以使用地图并设置

使用地图和集合:

(defn days-number-maker
  [all-days day-string]
  (let [day-set (set day-string)]
    (map (fn [day]
           (if (day-set day)
             1
             0))
         all-days)))
(defn days-to-numbers
  "Change string like MTTH to (1 1 0 1 0 0 0)"
  [day-string]
  (let [days (clojure.string/replace
               (clojure.string/replace day-string #"TH" "R") #"SU" "N")]
    (days-number-maker "MTWRFSN" days)))

这就是我更简洁的做法:

(defn days-to-numbers
  "Change string like MTTH to (1 1 0 1 0 0 0)"
  [week-string]
  (let [char-set (set (clojure.string/replace
                        (clojure.string/replace week-string "TH" "R") "SU" "N"))]
    (map #(if (char-set %) 1 0)
         "MTWRFSN")))

测试:

=> (days-to-numbers "")
(0 0 0 0 0 0 0)
=> (days-to-numbers "MTWTHFSSU")
(1 1 1 1 1 1 1)
=> (days-to-numbers "MTHSU")
(1 0 0 1 0 0 1)
=> (days-to-numbers "FM")
(1 0 0 0 1 0 0)

下面是@TheQuickBrownFox的回答。。。

  • 您不需要重新编码"TH""SU":第二个字母将做
  • 使用falsenil而不是0,这样您就可以直接应用逻辑测试
  • 将结果作为向量返回,正如您很可能想要的那样索引到其中

给予。。。

(defn days-to-numbers [ds]
  (let [dns (->> ds
             (partition-all 2 1)
             (remove #{[S U] [T H]})
             (map first)
             set)]
    (mapv dns "MTWHFSU")))

例如,

(days-to-numbers "MTTH")
;[M T nil H nil nil nil]

尽管函数名称错误,因为元素是逻辑值,而不是数字。


我更愿意返回的天数集合

(def day-index (into {} (map-indexed (fn [x y] [y x]) "MTWHFSU")))
;{M 0, T 1, W 2, H 3, F 4, S 5, U 6}
(defn day-numbers [ds]
  (->> ds
       (partition-all 2 1)
       (remove #{[S U] [T H]})
       (map (comp day-index first))
       set)) 

例如,

(day-numbers "MTTH")
;#{0 1 3}

最新更新