2009-02-05 8 views
7

Od pewnego czasu próbuję to sobie wyobrazić.Clojure "jeśli" nigdy nie ocenia swojego trzeciego argumentu.

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

To jest funkcja, którą napisałem. is-decimal jest albo przekazywana coś takiego jak "2,5" lub "5" lub coś w tym rodzaju, ale zawsze używa drugiego argumentu if, nigdy jego trzeciego. Przetestowałem w REPL (. astr (indexOf (int \.))) i wygląda na to, że działa poprawnie, zwraca -1, gdy się nie uda, a 1, gdy nie. Wierzę, że to może być problem. -1 nie oznacza fałszu w Clojure. Czy ktoś może wymyślić sposób, aby to naprawić?

Z góry dziękuję.

EDIT: Dzięki za pomoc facetów. Zaraz po tym, jak to napisałem, wpadłem na pomysł. Napisałem funkcję predykatu, która sprawdza 1 i -1. Dokładnie to, czego potrzebowałem. Nie należy kodować bezpośrednio po przebudzeniu: \

Odpowiedz

10

Jeśli chcesz sprawdzić, czy ciąg zawiera znak, można użyć wyrażenia regularnego:

(re-find #"\." astr) 

czyli

(some #(= \. %) astr) 

Lub:

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

Albo można użyć includes? z clojure.contrib.seq-utils który robi to zbyt.

Clojure posiada już czytnik, który potrafi odróżnić znaki typu int i debel, więc jeśli masz pewność, że Twój ciąg zawiera tylko cyfry, możesz go użyć. (Uważaj jednak, to czyta cokolwiek, nie tylko liczby.To jest potencjalnie niebezpieczne.Nie używaj tego, jeśli istnieje szansa, że ​​twój ciąg ma coś innego niż numer.)

Uwaga, Clojure obsługuje również przypadek, w którym liczba całkowita jest zbyt duża, aby zmieścić się w natywnym int bez przepełnienia. Jeśli chcesz przeanalizować liczby całkowite, lepiej przyjrzeć się funkcji bigint niż 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 

Jeśli funkcja jest predykatem, to powszechne w Clojure aby wymienić go decimal? zamiast is-decimal. Twoja funkcja jest raczej parserem liczb, więc osobiście nazwałbym go parse-number lub string-to-number.

+0

Jest to jedyna rzecz, której nie lubię w Clojure, nie mam pojęcia, jaką funkcję szukam: \ – Rayne

+0

Tak, doktorzy są dość nieliczni. Musisz usiąść i przeczytać cały API pewnego dnia. "find-doc" również pomaga. Sprawdź również http://github.com/mmcgrana/clj-doc/tree/master –

+2

Arkusz oszustów Clojure jest również bardzo pomocny: http://clojure.org/cheatsheet – ollb

2

dobrze, jeśli to nie zwracają -1 jeśli nie jest on następnie sprawdzić -1 i return false jeśli jest

6

Nietestowane:

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

Twoja odpowiedź była najbliższa temu, co zrobiłem, więc ją wybrałem. – Rayne

Powiązane problemy