2009-02-05 12 views
7

He estado tratando de entender esto desde hace un tiempo.Clojure 'si' nunca evaluando su tercer argumento

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

Esa es la función que escribí. is-decimal o se pasa algo como "2.5" o "5" o algo por el estilo, pero siempre usa el segundo argumento de if, nunca el tercero. Probé (. astr (indexOf (int \.))) en el REPL, y parece estar funcionando bien, devuelve -1 cuando falla y 1 cuando no funciona. Creo que ese podría ser el problema. -1 no significa falso en Clojure. ¿Alguien puede pensar en una forma de solucionar esto?

Gracias de antemano.

EDIT: Gracias por la ayuda chicos. Justo después de escribir esto, tuve una idea. Escribí una función de predicado que busca 1 y -1. Justo lo que necesitaba. No debería código directamente después de despertarse: \

Respuesta

10

Si desea comprobar si una cadena contiene un carácter, puede utilizar una expresión regular:

(re-find #"\." astr) 

O:

(some #(= \. %) astr) 

O:

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

O puede utilizar includes? de clojure.contrib.seq-utils que hace esto también.

Clojure ya tiene un lector que sabe cómo distinguir los datos de entrada y de doble, por lo que si está seguro de que su cadena solo tiene números, puede usarlo. (Tenga cuidado, esto lee cualquier cosa, no solo números. Esto es potencialmente peligroso. No use esto si hay alguna posibilidad de que su cuerda tenga algo más que un número.)

Nota, Clojure también maneja el caso donde El número entero es demasiado grande para caber en un int nativo sin desbordamiento. Si desea analizar enteros, es posible que desee examinar la función bigint en lugar de 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 

Si su función es un predicado, que es común en Clojure nombrarlo decimal? en lugar de is-decimal. Su función en realidad es más un analizador de números, así que personalmente lo llamaría parse-number o string-to-number.

+0

Esto es lo único que odio de Clojure, no tengo manera de saber qué función estoy buscando: \ – Rayne

+0

Sí, los documentos son bastante escasos. Tienes que sentarte y leer todo el API un día. 'find-doc' también ayuda. También consulte http://github.com/mmcgrana/clj-doc/tree/master –

+2

La hoja de trucos de Clojure también es muy útil: http://clojure.org/cheatsheet – ollb

2

bien si no devuelven -1 si falla a continuación, comprobar para el -1 y devolver false si es

6

No comprobado:

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

Tu respuesta fue la más cercana a la que hice, así que la elegí. – Rayne

Cuestiones relacionadas