我正在学习clojure,我写了这段代码来解决罗马数字kata:
(def romans (sorted-map-by >
1000 "M"
500 "D"
400 "CD"
100 "C"
90 "XC"
50 "L"
40 "XL"
10 "X"
9 "IX"
5 "V"
4 "IV"
1 "I"))
(defn roman-digit [arabic]
(first (filter (fn [[key value]]
(>= arabic key)) romans)))
(defn arabic-to-roman [arabic]
(def roman (roman-digit arabic))
(if (> arabic 0)
(apply str (val roman) (arabic-to-roman (- arabic (key roman))))
""))
我想知道如何让这段代码更有效/惯用/干净。我确信我可以学到很多新东西。
感谢。
答案 0 :(得分:2)
这是我的捅。
(defn roman-digit [arabic]
(first
(filter #(>= arabic (first %))
[[1000 "M" ]
[500 "D" ]
[400 "CD"]
[100 "C" ]
[90 "XC"]
[50 "L" ]
[40 "XL"]
[10 "X" ]
[9 "IX"]
[5 "V" ]
[4 "IV"]
[1 "I" ]])))
(defn arabic-to-roman [arabic]
(when (> arabic 0)
(let [[arabic-diff roman] (roman-digit arabic)]
(apply str roman (arabic-to-roman (- arabic arabic-diff))))))
这里发生了什么?
def
。将def
视为全局变量(符号)的声明和定义。对于本地范围(绑定),请使用let
。when
优先于if
,特别是如果只有一个分支。请注意,str
和apply
都为nil
做了正确的事情(当arabic
为0时,它会在递归的底部返回。)