2015-03-27 3 views
0

Для части проекта класса мне нужно прочитать в файле, представляющем граф в Clojure. Вот пример файла с файлом link to. Структура файла для всех файлов, которые я мог читать в таких`.split` метод в clojure возвращает неожиданные результаты

c Unknown number of lines 
c That start with "c" and are just comments 
c The rest of the lines are edges 
e 2 1 
e 3 1 
e 4 1 
e 4 2 
e 4 3 
e 5 1 
e 5 2 

вопрос, который я имею пытаюсь split линию, основанных на пространствах. В моей РЕПЛ я сделал

finalproject.core> (.split "e 1 2" " ") 
#<String[] [Ljava.lang.String;@180f214> 

Что, я не уверен, что это значит, точно .. Я думаю, что это относится к области памяти одного String[] я не знаю, почему он отображается так же. Если вставить # в передней части разделенной строки, которые я думаю, что означает, что это регулярное выражение, которое я получаю ошибку

finalproject.core> (.split "e 1 2" #" ") 
ClassCastException java.util.regex.Pattern cannot be cast to java.lang.String 

В настоящее время вся моя реализация этого модуля, который я уверен, что будет работать, если я может правильно использовать функцию split.

(defn lineToEdge [line] 
    (cond (.startsWith line "e") 
     (let [split-line (.split line " ") 
       first-str (split-line 1) 
       second-str (split-line 2)] 
      ((read-string first-str) (read-string second-str))))) 

(defn readGraphFile [filename, numnodes] 
    (use 'clojure.java.io) 
    (let [edge-list 
     (with-open [rdr (reader filename)] 
      (doseq [line (line-seq rdr)] 
      (lineToEdge line)))] 
    (reduce add-edge (empty-graph numnodes) edge-list))) 

У меня не было возможности протестировать readGraphFile в любом случае, но когда я пытаюсь использовать lineToEdge с некоторым фиктивным входом я получаю ошибку

finalproject.core> (lineToEdge "e 1 2") 
ClassCastException [Ljava.lang.String; cannot be cast to clojure.lang.IFn 

предложения о том, где я пошло не так?

ответ

2

В приведенном ниже примере возвращаемое значение представляет собой массив типа String.

finalproject.core> (.split "e 1 2" " ") 
#<String[] [Ljava.lang.String;@180f214> 

Чтобы использовать его более удобным в Clojure, вы можете поместить его в вектор:

user=> (vec (.split "e 1 2" " ")) 
["e" "1" "2"] 

Вы также можете использовать встроенный в clojure.string имен:

user=> (require '[clojure.string :as string]) 
nil 
user=> (string/split "e 1 2" #" ") 
["e" "1" "2"] 

источника ваш счетчик стека находится здесь:

(let [split-line (.split line " ") 
     first-str (split-line 1) 
     second-str (split-line 2)] ...) 

Это получает массив строк, через .split, затем пытается вызвать его, как если бы это была функция. Возможно, вы хотели использовать get здесь, чтобы получить доступ к элементу списка по индексу? (get split-line 1) получит элемент из split-line с индексом 1 и т.д.

Вы увидите другую проблему здесь:

((read-string first-str) (read-string second-str)) 

Если я читаю ваш код правильно, это будет в конечном итоге вызов номер, как если бы были функцией, с другим числом в качестве аргумента. Возможно, вы намерены вернуть пару чисел?

[(read-string first-str) (read-string second-str)] 
+0

Что 'функция split' используется, если не' 'clojure.string.split', когда (требуется«[clojure.string: в качестве строки]) 'не используется? // В чем разница между '(use 'clojure.java.io)' и '(require' [clojure.string: as string])'? – KDecker

+0

обозначение '.' указывает на вызов метода, это родной java split – noisesmith

+1

Значение, возвращаемое' String.split', на самом деле представляет собой массив строк - 'String []' или '[Ljava.lang.String;' в низкоуровневый JVM lingo - а не 'java.util.List'. Кроме того, '(vec (.split ...))' здесь предпочтительнее, потому что для коротких векторов (длиной до 32 элементов) 'vec' просто переносит вектор вокруг массива (используя его как хвост нового вектора). Это, конечно, только ОК, если известно, что массив безопасен от модификации, что в данном случае есть. ('string/split' реализован с использованием детали реализации Clojure, которая работает как' vec' в этом отношении.) –

Смежные вопросы