保存+读取排序的地图到Clojure中的文件 [英] Saving+reading sorted maps to a file in Clojure
问题描述
我通过 spit
将数据的嵌套地图保存到磁盘。我想要我的地图里面的一些地图被排序,并保持排序,当我 slurp
地图回我的程序。排序的地图没有唯一的字面值表示,因此当I spit
将地图映射到磁盘上时,排序的地图和未排序的地图都表示相同, #(read-string(slurp%))
使数据使每个映射通常是未排序的类型。这里是一个玩具示例说明这个问题:
I'm saving a nested map of data to disk via spit
. I want some of the maps inside my map to be sorted, and to stay sorted when I slurp
the map back into my program. Sorted maps don't have a unique literal representation, so when I spit
the map-of-maps onto disk, the sorted maps and the unsorted maps are represented the same, and #(read-string (slurp %))
ing the data makes every map the usual unsorted type. Here's a toy example illustrating the problem:
(def sorted-thing (sorted-map :c 3 :e 5 :a 1))
;= #'user/sorted-thing
(spit "disk" sorted-thing)
;= nil
(def read-thing (read-string (slurp "disk")))
;= #'user/read-thing
(assoc sorted-thing :b 2)
;= {:a 1, :b 2, :c 3, :e 5}
(assoc read-thing :b 2)
;= {:b 2, :a 1, :c 3, :e 5}
有没有什么方法可以读取地图在排序的第一位,而不是在阅读后转换为排序地图?或者这是一个迹象,我应该使用某种真实的数据库?
Is there some way to read the maps in as sorted in the first place, rather than converting them to sorted maps after reading? Or is this a sign that I should be using some kind of real database?
推荐答案
* print -dup *
动态重新绑定Var是为了支持此用例:
The *print-dup*
dynamically rebindable Var is meant to support this use case:
(binding [*print-dup* true]
(prn (sorted-map :foo 1)))
; #=(clojure.lang.PersistentTreeMap/create {:foo 1})
注释掉的行是
当应用到Clojure数据结构时,它也会影响 str
,因此 spit
,所以如果你做
It so happens that it also affects str
when applied to Clojure data structures, and therefore also spit
, so if you do
(binding [*print-dup* true]
(spit "foo.txt" (sorted-map :foo 1)))
写入 foo.txt
的地图表示将是上面显示的。
the map representation written to foo.txt
will be the one displayed above.
诚然, m不是100%确定这是否记录在某处;如果你对此感到不安,你总是可以 spit
使用 pr-str
与 * print-dup *
绑定到 true
:
Admittedly, I'm not 100% sure whether this is documented somewhere; if you feel uneasy about this, you could always spit
the result of using pr-str
with *print-dup*
bound to true
:
(binding [*print-dup* true]
(pr-str (sorted-map :foo 1)))
;= "#=(clojure.lang.PersistentTreeMap/create {:foo 1})"
(这次最后一行是返回的值而不是打印输出。 )
(This time the last line is the value returned rather than printed output.)
显然,你必须将 * read-eval *
绑定到 true
才能读回这些文字。这很好,但它的目的是为了(从可信来源读取代码)。
Clearly you'll have to have *read-eval*
bound to true
to be able to read back these literals. That's fine though, it's exactly the purpose it's meant to serve (reading code from trusted sources).
这篇关于保存+读取排序的地图到Clojure中的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!