序列化拉链?

时间:2012-04-30 21:58:31

标签: serialization clojure zipper

repl> (-> root zip/down zip/right)
[{:answer-keys [5 6], :id 3} {:l [{:id 2, :answer-keys []}], :pnodes [{:answer-keys [2 3 4], :id 1}], :ppath nil, :r ({:answer-keys [7], :id 4})}]

当我在repl上打印出拉链时,我看到了这些数据。我想这可能是我需要序列化拉链的所有数据?是否可以从提供的数据中反序列化拉链?

我正在寻找下面想象的zip / serialize和zip / deserialize函数。

(def s (zip/serialize (-> root zip/down zip/right))) ;; s is a string
(def d (zip/deserialize s)) ;; d is a zipper location
;;And I can go on using the deserialized zipper d without any difficulty.

有谁知道怎么做?

2 个答案:

答案 0 :(得分:4)

拉链的神奇之处在于它们是一种数据结构,代表了生成树结构的任意修改版本所需的一切。 拉链打印并阅读正常因为它们正确值且不需要任何状态

您可以使用pr-str“序列化”它并使用read“反序列化”它

制作拉链:

user> (zip/vector-zip [[1 [2]][3][4]])
[[[1 [2]] [3] [4]] nil]
user> (def s (zip/vector-zip [[1 [2]][3][4]]))
#'user/s
user> s
[[[1 [2]] [3] [4]] nil]

将其序列化为字符串:

user> (def serialized-s (pr-str (zip/next s)))
#'user/serialized-s
user> serialized-s
"[[1 [2]] {:l [], :pnodes [[[1 [2]] [3] [4]]], :ppath nil, :r ([3] [4])}]"

读回来:

user> (def deserialized-s (read-string "[[1 [2]] {:l [], :pnodes [[[1 [2]] [3] [4]]], :ppath nil, :r ([3] [4])}]"))
#'user/deserialized-s

对结果做一些事情:

user> (zip/root deserialized-s)
[[1 [2]] [3] [4]]

答案 1 :(得分:3)

扩展亚瑟的答案:

您可能还需要序列化clojure.zip放在其拉链上的元数据,因为这似乎是跟踪branch? / children / make-node函数的位置。像

这样的东西
(defn serialize [zipper]
  (binding [*print-meta* true]
    (pr-str zipper)))

(def deserialize read-string)