clojure java.lang.NullPointerException при разбиении строки - PullRequest
0 голосов
/ 22 января 2019

Я новичок в 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)

Спасибо ввперед.

Ответы [ 2 ]

0 голосов
/ 23 января 2019

Как указано в комментариях, первая проблема заключается в том, что вы не пишете правильный 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.

0 голосов
/ 22 января 2019

Я предлагаю вам использовать библиотеку CSV:

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

Если это не файл с упражнением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...