我是Clojure的新手。我试图编写一个程序,在读取数据后从文件(逗号分隔的文件)中读取数据,我试图在定界符“,”中拆分每一行,但我遇到以下错误:
CompilerException java.lang.NullPointerException, 编译:(com \ clojure \ apps \ StudentRanks.clj:26:5)
这是我的代码:
(ns com.clojure.apps.StudentRanks)
(require '[clojure.string :as str])
(defn student []
(def dataset (atom []))
(def myList (atom ()))
(def studObj (atom ()))
(with-open [rdr (clojure.java.io/reader "e:\\example.txt")]
(swap! dataset into (reduce conj [] (line-seq rdr)))
)
(println @dataset)
(def studentCount (count @dataset))
(def ind (atom 0))
(loop [n studentCount]
(when (>= n 0)
(swap! myList conj (get @dataset n))
(println (get @dataset n))
(recur (dec n))))
(println myList)
(def scount (count @dataset))
(loop [m scount]
(when (>= m 0)
(def data(get @dataset m))
(println (str/split data #","))
(recur (dec m))))
)
(student)
谢谢。
答案 0 :(得分:1)
正如评论中指出的那样,第一个问题是您没有编写正确的Clojure。
首先,def
绝对不能嵌套-它不会像您希望的那样运行。使用let
引入局部变量(通常仅称为局部变量,因为将变量称为不变的东西很奇怪)。
其次,类似块的构造(例如do
,let
或with-open
会求出其最后一个表达式的值。
因此,这段代码
(def dataset (atom []))
(with-open [rdr (clojure.java.io/reader "e:\\example.txt")]
(swap! dataset into (reduce conj [] (line-seq rdr))))
应该写
(let [dataset
(with-open [rdr (clojure.java.io/reader "e:\\example.txt")]
(into [] (line-seq rdr)))]
; code using dataset goes here
)
然后,您尝试通过向后遍历并将其约束在正在构建的列表中,将数据集(向量)转换为列表(myList
)。不需要您可以通过在向量上调用seq
来从向量中获得序列(类似列表)。 (或者,rseq
,如果您希望列表被倒转。)
最后,您再次迭代以拆分并打印dataset
中保存的每个项目。在Clojure中,带索引的显式迭代非常少见,更喜欢使用reduce
,doseq
,into
等。
有两种写student
的方法:
(defn student [] ; just for print
(with-open [rdr (clojure.java.io/reader "e:\\example.txt")]
(doseq [data (line-seq rdr)]
(println (str/split data #",")))))
(defn student [] ; to return a value
(with-open [rdr (clojure.java.io/reader "e:\\example.txt")]
(into []
(for [data (line-seq rdr)]
(str/split data #",")))))
我希望这可以帮助您更好地获得Clojure。
答案 1 :(得分:0)
我建议您使用csv库:
(require '[clojure.data.csv :as csv])
(csv/read-csv (slurp "example.txt"))
除非这是一些文件io练习。