Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure 'if' never evaluating its third argument

Tags:

clojure

I've been trying to figure this one our for a while now.

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

That is the function I wrote. is-decimal is either passed something such as "2.5" or "5" or something of the sort, but it always uses if's second argument, never its third. I tested (. astr (indexOf (int \.))) out in the REPL, and it seems to be working fine, it returns -1 when it fails and 1 when it doesn't. I believe that might be the problem. -1 doesn't mean false in Clojure. Can anyone think of a way to fix this?

Thanks in advance.

EDIT: Thanks for the help guys. Right after I wrote this I had an idea. I wrote a predicate function that checks for 1 and -1. Just what I needed. I shouldn't code directly after waking up :\

like image 899
Rayne Avatar asked Feb 05 '09 14:02

Rayne


3 Answers

If you want to test whether a string contains a character, you can use a regex:

(re-find #"\." astr)

Or:

(some #(= \. %) astr)

Or:

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

Or you can use includes? from clojure.contrib.seq-utils which does this too.

Clojure already has a reader that knows how to distinguish ints and doubles, so if you're sure your string only has numbers in it, you can use it. (Be careful though, this reads anything, not just numbers. This is potentially dangerous. Don't use this if there's any chance your string has something other than a number.)

Note, Clojure also handles the case where an integer is too big to fit into a native int without overflowing. If you want to parse integers, you might want to look at the bigint function rather than 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

If your function is a predicate, it's common in Clojure to name it decimal? rather than is-decimal. Your function actually is more of a number parser, so personally I'd call it parse-number or string-to-number.

like image 126
Brian Carper Avatar answered Nov 23 '22 17:11

Brian Carper


Untested:

(if (> 0 (. astr (indexOf (int \.))))
like image 43
Dan Avatar answered Nov 23 '22 17:11

Dan


well if it does return -1 if it fails then check for the -1 and return false if it is

like image 31
Josh Mein Avatar answered Nov 23 '22 16:11

Josh Mein