Vui lòng không sử dụng tính năng def lồng nhau. Nó không làm, những gì bạn nghĩ rằng nó. def luôn là toàn cầu! Thay vào đó, để người dân địa phương sử dụng thay thế. Trong khi các chức năng thư viện rất hay để biết, ở đây một phiên bản phối hợp một số tính năng của lập trình hàm nói chung và clojure nói riêng.
(import 'java.io.FileWriter 'java.io.FileReader 'java.io.BufferedReader)
(defn translate-coords
Tài liệu có thể được truy vấn trong REPL qua (doc translation-coords). Làm việc ví dụ. cho tất cả các chức năng cốt lõi. Vì vậy, cung cấp một là một ý tưởng tốt.
"Reads coordinates from infile, translates them with the given
translator and writes the result to outfile."
dịch là một hàm (có thể ẩn danh) trích xuất bản dịch từ bản mẫu xung quanh. Vì vậy, chúng tôi có thể tái sử dụng chức năng này với các quy tắc chuyển đổi khác nhau. Các gợi ý loại ở đây tránh sự phản ánh cho các nhà xây dựng.
[translator #^String infile #^String outfile]
Mở tệp. với mở sẽ cẩn thận, rằng các tập tin được đóng lại khi cơ thể của nó là trái. Có thể là thông qua "thả xuống đáy" bình thường hoặc là thông qua một ngoại lệ được ném.
(with-open [in (BufferedReader. (FileReader. infile))
out (FileWriter. outfile)]
Chúng tôi ràng buộc luồng *out*
tạm thời vào tệp đầu ra. Vì vậy, bất kỳ bản in nào bên trong liên kết sẽ in ra tệp.
(binding [*out* out]
map
có nghĩa là: lấy seq và áp dụng hàm cho mỗi phần tử và trả về kết quả. #()
là ký pháp viết tắt của một hàm ẩn danh. Phải mất một đối số, được điền vào tại số %
. Các doseq
về cơ bản là một vòng lặp trên đầu vào. Vì chúng ta làm điều đó cho các tác dụng phụ (cụ thể là in một tệp), doseq
là cấu trúc đúng. Quy tắc: map
: lazy => cho kết quả, doseq
: eager => cho các tác dụng phụ.
(doseq [coords (map #(.split % ",") (line-seq in))]
println
sẽ chăm sóc cho \n
ở cuối dòng. interpose
lấy seq và thêm đối số đầu tiên (trong trường hợp của chúng tôi "") giữa các phần tử của nó. (apply str [1 2 3])
tương đương với (str 1 2 3)
và hữu ích để xây dựng các cuộc gọi hàm động. Các ->>
là một vĩ mô tương đối mới trong clojure, giúp một chút với khả năng đọc. Nó có nghĩa là "lấy đối số đầu tiên và thêm nó làm mục cuối cùng cho cuộc gọi hàm". Số ->>
nhất định tương đương với: (println (apply str (interpose " " (translator coords))))
. (Chỉnh sửa: Một lưu ý: kể từ khi tách là \space
, chúng tôi có thể viết ở đây cũng như (apply println (translator coords))
, nhưng phiên bản interpose
cho phép cũng parametrize tách như chúng tôi đã làm với chức năng dịch, trong khi phiên bản ngắn sẽ hardwire \space
.)
(->> (translator coords)
(interpose " ")
(apply str)
println)))))
(defn survey->cartography-format
"Translate coords in survey format to cartography format."
Ở đây chúng tôi sử dụng destructuring (lưu ý đôi [[]]
). Nó có nghĩa là đối số cho hàm là cái gì đó có thể được biến thành một seq, ví dụ. một vector hoặc một danh sách. Liên kết phần tử đầu tiên với số y
, phần tử thứ hai là x
, v.v.
[[y x z p]]
[p x y z])
(translate-coords survey->cartography-format "survey_coords.txt" "cartography_coords.txt")
đây một lần nữa ít choppy:
(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")
Hope this helps.
Chỉnh sửa: Để đọc CSV, bạn có thể muốn một cái gì đó như OpenCSV.
'my ($ x, $ y, $ z, $ p) = chia /, /;' –
Điểm tốt - TIMTOWTDI. Cảm ơn. –