Пожалуйста, не используйте вложенные определения. Он не делает того, что вы думаете. def всегда глобальный! Для местных жителей используйте let вместо этого. Хотя библиотечные функции хорошо знать, здесь версия, в которой реализованы некоторые функции функционального программирования в целом и clojure в частности.
(import 'java.io.FileWriter 'java.io.FileReader 'java.io.BufferedReader)
(defn translate-coords
Строки документации можно запрашивать в REPL через (doc translate-coords). Работает напр. для всех основных функций. Так что поставка одного - хорошая идея.
"Reads coordinates from infile, translates them with the given
translator and writes the result to outfile."
переводчик — это (возможно, анонимная) функция, которая извлекает перевод из окружающего шаблона. Таким образом, мы можем повторно использовать эти функции с различными правилами преобразования. Подсказки типа здесь позволяют избежать отражения для конструкторов.
[translator #^String infile #^String outfile]
Откройте файлы. with-open позаботится о том, чтобы файлы были закрыты, когда его тело осталось. Будь то через обычное «выпадение со дна» или через выброшенное исключение.
(with-open [in (BufferedReader. (FileReader. infile))
out (FileWriter. outfile)]
Мы временно привязываем поток *out* к выходному файлу. Таким образом, любая печать внутри привязки будет напечатана в файл.
(binding [*out* out]
map означает: возьмите последовательность и примените данную функцию к каждому элементу и верните последовательность результатов. #() — это сокращенное обозначение анонимной функции. Он принимает один аргумент, который заполняется в %. doseq - это, по сути, петля над входом. Поскольку мы делаем это для побочных эффектов (а именно, печати в файл), doseq является правильной конструкцией. Эмпирическое правило: map: ленивый => для результата, doseq: нетерпеливый => для побочных эффектов.
(doseq [coords (map #(.split % ",") (line-seq in))]
println заботится о \n в конце строки. interpose берет последовательность и добавляет первый аргумент (в нашем случае " ") между своими элементами. (apply str [1 2 3]) эквивалентно (str 1 2 3) и полезно для динамического построения вызовов функций. ->> — относительно новый макрос в clojure, который немного улучшает читабельность. Это означает «взять первый аргумент и добавить его в качестве последнего элемента в вызов функции». Данное ->> эквивалентно: (println (apply str (interpose " " (translator coords)))). (Правка: еще одно примечание: поскольку разделителем является \space, мы могли бы здесь написать так же хорошо (apply println (translator coords)), но версия interpose позволяет также параметризовать разделитель, как мы сделали с функцией транслятора, в то время как короткая версия будет жестко привязана к \space.)
(->> (translator coords)
(interpose " ")
(apply str)
println)))))
(defn survey->cartography-format
"Translate coords in survey format to cartography format."
Здесь мы используем деструктурирование (обратите внимание на двойной [[]]). Это означает, что аргумент функции - это то, что можно превратить в последовательность, например. вектор или список. Привяжите первый элемент к y, второй к x и так далее.
[[y x z p]]
[p x y z])
(translate-coords survey->cartography-format "survey_coords.txt" "cartography_coords.txt")
Здесь снова менее изменчиво:
(import 'java.io.FileWriter 'java.io.FileReader 'java.io.BufferedReader)
(defn translate-coords
"Reads coordinates from infile, translates them with the given
translator and writes the result to outfile."
[translator #^String infile #^String outfile]
(with-open [in (BufferedReader. (FileReader. infile))
out (FileWriter. outfile)]
(binding [*out* out]
(doseq [coords (map #(.split % ",") (line-seq in))]
(->> (translator coords)
(interpose " ")
(apply str)
println)))))
(defn survey->cartography-format
"Translate coords in survey format to cartography format."
[[y x z p]]
[p x y z])
(translate-coords survey->cartography-format "survey_coords.txt" "cartography_coords.txt")
Надеюсь это поможет.
Изменить: для чтения CSV вам, вероятно, понадобится что-то вроде OpenCSV.
person
kotarak
schedule
17.11.2009