Reputation: 371
This should be an easy question, but I've spent several hours and I still don't understand how to properly use sets in Clojure. I'm attempting to read a file and store each line in a set. This is my code so far.
(def dictionary #{})
;(conj dictionary "hi")
(defn readDictionary []
(doseq [line (clojure.string/split-lines
(slurp "C:\\Working\\Other\\dictionary.txt"))]
(println line)
(conj dictionary line)))
(readDictionary)
(println dictionary)
I can append the "hi" string to the set and each line gets printed out within the doseq, but the set ends up blank when I print it out.
I've very familiar with OO programming, but functional programming is something new for me.
Upvotes: 3
Views: 209
Reputation: 2539
Read lines from file into set
(with-open [rdr (clojure.java.io/reader "C:\\Working\\Other\\dictionary.txt")]
(set (line-seq rdr)))
Upvotes: 1
Reputation: 13483
The problem is not with sets as such. The problem is that conj
, like most of the core library, does not have side effects. So the expression:
(conj dictionary line)
... evaluates to dictionary
with line
added to it, leaving dictionary
(and line
) quite unchanged. So the doseq
produces a sequence of sets, each containing one line.
The call
(readDictionary)
... evaluates this sequence of single-member sets, then discards it, since it is not bound to anything. Hence the call has no net effect.
I think you want something like this (untested):
(defn readDictionary [file-name]
(into #{} (clojure.string/split-lines (slurp file-name))))
(def dictionary (readDictionary "C:\\Working\\Other\\dictionary.txt"))
(doseq [line dictionary] (println line))
In Clojure, you have to get used to working with pure (side-effect free) functions operating upon immutable/persistent data structures.
Upvotes: 6