Мне нужно написать функцию, которая разбивает записи на отдельные файлы в зависимости от значения поля.Например, с учетом ввода:
[
["Paul" "Smith" 35]
["Jason" "Nielsen" 39]
["Charles" "Brown" 22]
]
В итоге мы получим файл "Paul"
, содержащий "Paul Smith 35"
, файл "Jason"
, содержащий "Jason Nielsen 39"
и т. Д.
Не знаюЯ не знаю имен заранее, поэтому мне нужно сохранить ссылки на авторов, чтобы я мог закрыть их в конце.
Лучшее, что я мог придумать, - это использование ссылки для сохранения авторов, напримерэто:
(defn write-split [records]
(let [out-dir (io/file "/tmp/test/")
open-files (ref {})]
(try
(.mkdirs out-dir)
(dorun
(for [[fst lst age :as rec] records]
(binding [*out* (or
(@open-files fst)
(dosync
(alter open-files assoc fst (io/writer (str out-dir "/" fst)))
(@open-files fst)))]
(println (apply str (interpose " " rec))))))
(finally (dorun (map #(.close %) (vals @open-files)))))))
Это работает, но чувствует себя ужасно и, что более важно, заканчивается куча, хотя у меня есть только пять выходных файлов, которые открыты в самом начале.Кажется, что-то как-то сохраняется ...
Кто-нибудь может подумать о более функциональном и Clojure-подобном решении?
РЕДАКТИРОВАТЬ: Вход большой.Потенциально гигабайты данных, отсюда важность эффективности памяти и нежелание закрывать файлы после каждой записи.