我需要根据第一个字符做出关于字符串的决定,并且我有一个以这种方式定义的方法:
(defn check-first [string]
(case (get string 0)
"+" 1
"-" 2
3
))
目前,即使字符串以这些字符开头,它也始终返回3。我究竟做错了什么?另外,有更优雅的方式来实现这个吗?
答案 0 :(得分:10)
(get "foo" 0)
;; => \f
(get "foo" 0)
会返回char
,而不是string
,因此,如果您想使用check-first
,则需要用字符替换字符串。< / p>
(defn check-first [s]
(case (first s) \+ 1, \- 2, 3))
顺便说一句,Clojure Library Coding Standards
建议使用s
作为需要字符串输入的函数的参数名称。
如果您希望使用字符串代替字符:(str (first "foo"))
或(subs "foo" 0 1)
=> "f"
或者,可以编写case-indexed
宏。
以下是快速入侵,并没有为默认表达式提供选项:
(defmacro case-indexed [expr & clauses]
(list* 'case expr (interleave clauses (iterate inc 1))))
;; (case-indexed "foo" "bar" "baz" "foo") => 3
;; (case-indexed (+ 5 1) 3 4 5 6 7) => 4
(defn check-first [s]
(case-indexed (first s)
\+, \-, \*, \/))
我认为我不会将这样的条款分开 - 这只是为了让答案更加简洁。
我建议扩展case-indexed
用于默认表达式,如果要使用它的话。此外,check-first
似乎对此函数的名称过于笼统;我没有更好的建议,但我会考虑改变它。 (假设它不是为了这个问题而编造的。)
答案 1 :(得分:3)
您可以保留所拥有的内容,并在您的案例条件中使用Java的子字符串方法:
(defn check-first [s]
(case (.substring s 0 1)
"+" 1
"-" 2
3))
修改:刚刚注意到MayDaniel已经提到了subs
,其工作方式与.substring
相同。对不起,现在就在这里......
答案 2 :(得分:-3)
你的意思是使用cond吗?
http://clojure-notes.rubylearning.org/
(def x 10)
(cond
(< x 0) (println "Negative!")
(= x 0) (println "Zero!"))
; => nil
(cond
(< x 0) (println "Negative!")
(= x 0) (println "Zero!")
:default (println "Positive!"))
; => Positive!