请不要使用嵌套的 def。它不会做你认为它会做的事。 def 始终是全局的!对于当地人来说,请使用 let 代替。虽然库函数很高兴了解,但这里的版本总体上协调了函数式编程的一些功能,特别是 clojure。
(import 'java.io.FileWriter 'java.io.FileReader 'java.io.BufferedReader)
(defn translate-coords
文档字符串可以通过 (doc translate-coords) 在 REPL 中查询。作品例如。对于所有核心功能。因此,提供一个是一个好主意。
"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]
The map
意思是:获取 seq 并将给定函数应用于每个元素并返回结果的 seq。这#()
是匿名函数的简写符号。它需要一个参数,该参数填写在%
. The doseq
基本上是输入的循环。由于我们这样做是为了产生副作用(即打印到文件),doseq
是正确的构造。经验法则:map
: 懒惰=>结果,doseq
: 渴望 => 副作用。
(doseq [coords (map #(.split % ",") (line-seq in))]
println
照顾\n
在线的末尾。interpose
接受 seq 并在其元素之间添加第一个参数(在我们的例子中为“”)。(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."
这里我们使用解构(注意双[[]]
)。这意味着函数的参数可以转换为 seq,例如。向量或列表。将第一个元素绑定到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 之类的东西。