clojure - 在 Clojure/EDN 中序列化排序的映射?

标签 clojure sortedmap edn

如何在 Clojure 中序列化和反序列化已排序的映射?

例如:

(sorted-map :a 1 :b 2 :c 3 :d 4 :e 5)
{:a 1, :b 2, :c 3, :d 4, :e 5}

我注意到的:

  1. 已排序 map 的显示方式与 REPL 中未排序 map 的显示方式相同。这有时看起来很方便,但有时却很不方便。
  2. EDN不支持 sorted maps .
  3. Clojure 支持 custom tagged literals for the reader .

其他资源:

最佳答案

相同的问题有两个可用的答案:Saving+reading sorted maps to a file in Clojure .

第三个答案是设置自定义阅读器文字。你会像这样打印排序的 map

;; non-namespaced tags are meant to be reserved
#my.ns/sorted-map {:foo 1 :bar 2}

然后在读取时使用适当的数据函数(从 HashMap 转换为排序图)。您可以选择是否要处理自定义比较器(这是一个通常无法解决的问题,但当然可以选择处理特殊情况)。

clojure.edn/read 接受一个可选的 opts 映射,它可能包含一个 :reader 键;然后将该键的值作为一个映射,指定哪些数据读取器用于哪些标签。有关详细信息,请参阅 (doc clojure.edn/read)

至于打印,您可以为 print-method 安装自定义方法或使用自定义函数来打印排序的 map 。我可能会选择后一种解决方案——为内置类型实现内置协议(protocol)/多重方法通常不是一个好主意,所以即使在特定情况下看起来合理,也需要格外小心等;使用自己的功能更简单。

更新:

演示如何干净地重用 IPersistentMapprint-method impl,正如对 David 的回答的评论中所 promise 的那样:

(def ^:private ipm-print-method
  (get (methods print-method) clojure.lang.IPersistentMap))

(defmethod print-method clojure.lang.PersistentTreeMap
  [o ^java.io.Writer w]
  (.write w "#sorted/map ")
  (ipm-print-method o w))

有了这个:

user=> (sorted-map :foo 1 :bar 2)
#sorted/map {:bar 2, :foo 1}

关于clojure - 在 Clojure/EDN 中序列化排序的映射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18118290/

相关文章:

clojure - 语法 : hash (pound) then symbol

java - 根据另一个数组对数组进行排序

Java SortMap 比较器在字母键之后排列数字键

templates - Clojure EDN 作为代码生成元数据源

clojure - 修改 clojure 代码时有没有保留注释的好方法?

macros - clojure 宏中#/% 的嵌套

clojure - ^{ 是什么意思?

clojure - 如何获取 clojure 数组映射来维护 assoc 之后的插入顺序?

Scala:为什么 SortedMap 的 mapValues 返回的是 Map 而不是 SortedMap?

clojure - 调用从 EDN 文件中读取的函数