coco
coco

Reputation: 231

Error when using Integer/parseInt with map in Clojure

I'm learning Clojure and am confused by the following:

(vector "1")
;; returns ["1"]

(map vector '("1" "2" "3"))
;; returns (["1"] ["2"] ["3"])

However:

(Integer/parseInt "1")
;; returns 1

(map Integer/parseInt '("1" "2" "3"))
;; throws error "Unable to find static field: parseInt in class java.lang.Integer"

Instead, I need:

(map #(Integer/parseInt %) '("1" "2" "3"))
;; returns (1 2 3)

If I can use a function like vector with map, why can't I use Integer/parseInt?

Upvotes: 19

Views: 3591

Answers (3)

Christian
Christian

Reputation: 4593

Have a look at the Stack Overflow question Convert a sequence of strings to integers (Clojure). The answer says: You have to wrap Integer/parseInt in an anonymous function because Java methods aren't functions.

Upvotes: -1

nickik
nickik

Reputation: 5881

You have to wrap it in #() or (fn ...). This is because Integer/parseInt is a Java method and Java methods can't be passed around. They don't implement the IFn interface.

Clojure is built on Java and sometimes this leaks through, and this is one of those cases.

Upvotes: 24

mikera
mikera

Reputation: 106401

As others have stated, you need to wrap Integer/parseInt in order to convert it from a Java method into a Clojure function:

(map #(Integer/parseInt %) '("1" "2" "3"))

The reason for this is that Clojure functions must implement the IFn interface in order to be passed as arguments into higher order functions such as map.

This is a little bit ugly if you are doing this kind of conversion many times, so I'd recommend wrapping your parse-int function as follows:

(defn parse-int [s] (Integer/parseInt s))

(map parse-int '("1" "2" "3"))

As a final alternative, you may want to use the built-in read-string function - this will return integers in your case but would also work for doubles etc.:

(map read-string '("1" "2" "3"))

Upvotes: 6

Related Questions