保存+读取排序的地图到Clojure中的文件 [英] Saving+reading sorted maps to a file in Clojure

查看:129
本文介绍了保存+读取排序的地图到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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆