2009-02-05 18 views
7

我一直在努力想象这个我们有一段时间了。Clojure'如果'从来没有评估过它的第三个参数

(defn is-decimal [astr] 
    (if (. astr (indexOf (int \.))) 
    (Double/parseDouble astr) 
    (Integer/parseInt astr))) 

这是我写的函数。 is-decimal要么通过诸如“2.5”或“5”之类的东西,但总是使用if的第二个参数,而不是第三个参数。我在REPL中测试了(. astr (indexOf (int \.))),它似乎工作正常,它在失败时返回-1,在失败时返回1。我相信这可能是问题所在。在Clojure中-1并不意味着错误。任何人都可以想办法解决这个问题吗?

在此先感谢。

编辑:谢谢你们的帮助。在我写这篇文章之后,我有了一个想法。我写了一个谓词函数来检查1和-1。正是我需要的。我不应该醒来后直接代码:\

回答

10

如果你想测试一个字符串是否包含一个字符,你可以使用正则表达式:

(re-find #"\." astr) 

或者:

(some #(= \. %) astr) 

或者:

(contains? (into #{} astr) \.) 

或者你可以使用从clojure.contrib.seq-utilsincludes?该做这件事的。

Clojure已经有了一个知道如何识别整数和双精度的读者,所以如果你确定你的字符串只有数字,你可以使用它。 (注意,尽管这只是读取任何内容,而不仅仅是数字,这是潜在的危险,如果您的字符串有其他数字以外的任何其他字符,请不要使用它。)

请注意,Clojure还处理整数太大而无法满足本地int而没有溢出。如果你想解析整数,你可能想看看bigint函数而不是parseInt

user> (class (read-string "2.5")) 
java.lang.Double 
user> (class (read-string "2")) 
java.lang.Integer 
user> (class (read-string "2000000000000")) 
java.math.BigInteger 

如果你的函数是一个断言,这是常见的用Clojure来命名它decimal?而非is-decimal。你的功能实际上是更多的数字解析器,所以我个人称之为parse-numberstring-to-number

+0

这是我唯一讨厌Clojure的东西,我无法知道我在找什么功能:\ – Rayne 2009-02-06 21:10:27

2

好,如果它返回-1,如果失败则检查-1并返回false如果它是

6

未经测试:

(if (> 0 (. astr (indexOf (int \.)))) 
+0

您的回答与我所做的最接近,所以我选择了它。 – Rayne 2009-02-05 14:30:00