2
votes

A json-encoded string is passed into my function, and I need to split that string based on a delimiter, then convert the first two delimited values into integers and assign them to variables which will be used within the function. I've got code that works, though it looks clumsy to me.

(:use [clojure.string :only (split trim)])
(:use [clojure.data.json :only (json-str write-json read-json)])

(defn parse-int [s] (Integer. (re-find #"[0-9]*" s)))

(map parse-int (take 2
  (map trim (seq (.split #"\|"
    (read-json "\" 123 | 456 | 789 \""))))))

I've hard-coded my sample input value for simplicity and so it's easily reproduced in a REPL.

I expect the result: (123 456) (which, in my code, is assigned to (let [[a b])

As I said, this code works, but I feel I must be missing something that would make it less ugly, more idiomatic.

1
I did simplify this a bit by enhancing (er, fixing) my parse-int: (defn parse-int [s] (Integer. (re-find #"[0-9]+" s))) So now I don't need the trim. (map parse-int (take 2 (seq (.split #"\|" (read-json "\" 123 | 456 | 789 \""))))) - pwinn
And given that Clojure is good about let, I can drop the (take 2 bit as well. That might mean the parse-int is happening more often than it should, but in this case I don't think I'm worried about that. So now it's (map parse-int (seq (.split #"\|" (read-json "\" 123 | 456 | 789 \"") ))) - pwinn

1 Answers

1
votes

I think this is clearer:

(:use [clojure.string :only (split trim)])
(:use [clojure.data.json :only (read-json)])

(map #(Integer/valueOf (trim %)) 
     (split (read-json input) #"\|"))

assuming input is your input string.

Integer/valueOf (alternatively Integer/parseInt) seems to be the main thing your missing. No need for regex.