I have data in a text file formatted like this:
1 2
3 4
5 6
7 8
9 0
I want to create a list for each column, thus:
((1 3 5 7 9) (2 4 6 8 0))
I've actually come up with a working solution:
(defn make-lists []
(let [lines (clojure.string/split-lines (slurp "input"))]
(let [l1 (map #(parse-long (first (clojure.string/split % #" "))) lines)
l2 (map #(parse-long (nth (clojure.string/split % #" ") 3)) lines)]
(list l1 l2))))
However, I think there are some issues with this solution. I'm not actually sure how map
works under the hood, but I fear this results in two iterations over the input when theoretically one should suffice.
Unfortunately there is more than one space that separates the two values on each line in the input data. And clojure.string/split
produces a result for every single one. Hence I have this arbitrary looking nth 3
for l2 in my code that I would like to get rid of.
I'd appriciate any idea how to improve on this code.
In general, you shouldn't care that much about iterating more than once over something. It's common, it's alright, consider optimizing it only if you have already proved it is a bottleneck.
Regarding spaces - that argument to str/split
is a regular expression. Just use #" +"
instead of #" "
.
With that in mind, this is how I'd do it:
(->> (clojure.string/split-lines "1 2\n3 4\n5 6\n7 8\n9 0")
(map #(map parse-long (clojure.string/split % #" +")))
(apply map list))