Best way to read the contents of a file in a set in Clojure

I am learning Clojure, and as an exercise I wanted to write something like the command "comm" unix.

To do this, I read the contents of each file in the set, and then use the difference / intersection to display exclusive / shared files.

After a lot of retries, I came up with something similar for the created part of the creation:

(def contents (ref #{})) (doseq [line (read-lines "/tmp/a.txt")] (dosync (ref-set contents (conj @contents line)))) 

(I use duck-streams / read-lines to determine the contents of the file).

This is my first hit in any functional programming or lisp / Clojure. For example, I could not understand why, when I was pairing on the set, the set was still empty. This led me to study links.

  • Is there a better Clojure / functional way to do this? Using ref-set, am I just twisting the code to non-functional thinking, or is my code consistent with how it should be done?
  • Is there a library that already does this? This seems like a relatively common thing, but I could not find anything like it.
+4
source share
2 answers

Clojure 1.3:

 user> (require '[clojure.java [io :as io]]) nil user> (line-seq (io/reader "foo.txt")) ("foo" "bar" "baz") user> (into #{} (line-seq (io/reader "foo.txt"))) #{"foo" "bar" "baz"} 

line-seq gives you a lazy sequence in which every element in the sequence is a line in the file.

into dumps all this into a set. To do what you tried to do (add each element one at a time), rather than doseq and refs, you can do:

 user> (reduce conj #{} (line-seq (io/reader "foo.txt"))) #{"foo" "bar" "baz"} 

Note that Unix comm compares two sorted files, which is probably a more efficient way to compare files than doing intersection sets.

Edit: Dave Ray is right, to avoid leaking open files, it is better to do this:

 user> (with-open [f (io/reader "foo.txt")] (into #{} (line-seq f))) #{"foo" "bar" "baz"} 
+7
source

I always read with slurp and then split with re-seq because of my needs.

0
source

Source: https://habr.com/ru/post/919898/


All Articles