2013. október 18., péntek

map, keep, filter, remove, some

clojure.core/map

map

map can be used to call a function for each element of a collection and replace them with the result of the function.

(map even? [1 2 3 4 5 6])
;=> [false true false true false true]

Tip: hash-maps can be used as functions, mapping keys to values.

(map {1 "one", 2 "two", 3 "three"} [2 1 1 3])
;=> ["two" "one" "one" "three"]


Tip: you can give multiple collections to this functions, the result will have the length of the shortest.

(map + [3 2 5 4] (range))
;=> (3 3 7 7)




ClojureScript string to integer

Str to int.

;; with some java interop
(Integer/parseInt "31") 
;; => 31

(Integer/parseInt "asd")
;; => NumberFormatException
;; okay then. we need to check for number format.

(defn str->int
  [s] 
  (when (re-matches #"^\d+$" s)
    (Integer/parseInt s)))

;; or a solution with no interop:

(defn str->int
  [s]
  (when (and (string? s)
        (re-find #"^\d+$" s))
    (read-string s)))


Problem

When dealing with external data in Clojure/ClojureScript, we often receive numeric values as strings from outer sources. Converting data to the right type is not always straightforward. Looking for a solution, I considered the following aspects.

Clean

Write small and straightforward functions. Use suggestive but short names and doc strings when needed.

Perform

Also, avoid interop when possible. When performance is a major issue, implementing your functions in native java is a winner anyways.

Secure

Be clear about use cases of functions. What do your functions do when arguments of wrong type are supplied? Did you think about nil arguments?

Also, please note: when using read-string, always bound *read-eval* to false to stop malicious data being executed. read-string drops a RuntimeException on malformed or empty string.