【问题标题】:clojure java.lang.NullPointerException while spliting string拆分字符串时的clojure java.lang.NullPointerException
【发布时间】:2019-01-22 13:37:12
【问题描述】:

我是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)

提前致谢。

【问题讨论】:

  • 不要在函数中使用def,使用let
  • 我的建议是放慢一点。作为 clojure 的新手,您可能想要考虑原子,交换!甚至循环为更高级的主题。您不需要任何这些东西来从文件中读取行并拆分它们。事实上,即使在相当复杂的程序中,你也很少需要它们 :-)
  • 我的要求是逐行读取文件内容并将每一行推入一个列表。例如:我的文件内容是“1,bharath,85,86,89,85”,要求是:[(1 bharath 85 86 89 85)]。

标签: clojure


【解决方案1】:

正如 cmets 中所指出的,第一个问题是您没有编写正确的 Clojure。 首先,def 不应该被嵌套——它不会像你希望的那样表现。使用let 引入局部变量(通常只称为局部变量,因为将变量称为不变的事物很奇怪)。 其次,块状结构(如doletwith-open 的计算结果为它们最后一个表达式的值。

所以这个sn-p

(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 中使用索引进行显式迭代非常不寻常,更喜欢 reducedoseqinto 等。

这里有两种写法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。

【讨论】:

  • 非常感谢cgrand。现在我明白了。
【解决方案2】:

我建议你使用 csv 库:

(require '[clojure.data.csv :as csv])
(csv/read-csv (slurp "example.txt"))

除非这是一些文件 io 练习。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-29
    • 1970-01-01
    • 2013-02-15
    • 2021-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多