(defn num-as-words [n]
(let [words '("zero" "one" "two" "three" "four"
"five" "six" "seven" "eight" "nine")]
(clojure.string/join "-"
(map (fn [x] (nth words (Integer. (re-find #"\d" (str x)) ))) (str n)))))
我已经将这个函数称为num-as-words,它取一个整数并将其显示为全字,例如,如果你输入(123)它将返回(一二三)。
我已经使用地图完成了它,但我想知道是否有其他方法可以做到这一点?我还想知道是否有另一种方法来连接单词而不是clojure.string / join,我最初使用的是interpose但不喜欢它输出的方式,因为它看起来像("一个&# 34;" - "" 2"" - "" 3")。
非常感谢任何帮助,谢谢。
答案 0 :(得分:5)
user=> (clojure.pprint/cl-format ; formatted printing
nil ; ... to a string
"~{~R~^-~}" ; format (see below)
(map ; map over characters
(fn [x] (Integer. (str x))) ; convert char to integer
(str 123))) ; convert number to string
"one-two-three"
首先,我们将输入数字(此处硬编码为"123"
)强制转换为字符串,并通过map
迭代生成的字符串字符。对于每个字符,我们构建一个包含该字符的字符串,并将其解析为Integer
。因此,我们获得了一个数字列表。
更确切地说,(fn [x] ...)
是一个带有一个参数的函数。您应该将其命名为char
而不是(抱歉),因为我们会迭代字符。当我们评估(str x)
时,我们获得一个包含一个char的字符串,即x
。例如,如果字符为\2
,则生成的字符串为"2"
。 (Integer. string)
形式(注意点!)调用Integer
类的构造函数,该类将字符串解析为整数。要继续我们的示例,(Integer. "2")
将产生整数2。
我们使用cl-format
将数字列表打印成一个新字符串(由false
参数请求)。为此,我们指定格式如下:
~{...~}
遍历列表并在每个元素的大括号内执行格式。
~R
打印一个数字作为英文单词(1 => one等)~^
转义~{...~}
进行的迭代。因此,当我们打印最后一位数字时,不会打印~^
后面的部分。~^
后面的内容只是字符-
。这用于分隔字符串,但我们必须注意不要为循环的所有迭代打印破折号,否则结果字符串将以破折号结束。如果无法将任何字符解析为整数,则该函数将报告错误。在将输入转换为字符串之前,您可能需要首先检查输入是否为正整数。
答案 1 :(得分:3)
我会像这样实现它:
(defn num-as-words [n]
(let [words ["zero" "one" "two" "three" "four" "five" "six" "seven" "eight" "nine"]]
(->> (str n)
(map #(Character/getNumericValue %))
(map words)
(clojure.string/join "-"))))
Charactor/getNumericValue
将char转换为整数。->>
宏。clojure.string/join
看起来不错。interpose
返回延迟序列。这就是它返回("one" "-" "two"...)
的原因。您应该apply str
结果(apply str (interpose ...))
将其转换为字符串。如果您想处理负数,可以像这样修改代码:
(defn num-as-words [n]
(if (< n 0)
(str "-" (num-as-words (- n)))
(let [words ["zero" "one" "two" "three" "four" "five" "six" "seven" "eight" "nine"]]
(->> (str n)
(map #(Character/getNumericValue %))
(map words)
(clojure.string/join "-")))))
这将在前面添加-
。如果您只想抛出错误,可以使用前置条件:
(defn num-as-words [n]
{:pre [(<= 0 n)]}
(let [words ["zero" "one" "two" "three" "four" "five" "six" "seven" "eight" "nine"]]
...
当收到负数时,这将抛出AssertionError
。