如何在结构中移动元素,可能使用拉链?

How to move an element within a structure, possibly with zippers?

我有这样的结构:

 [{"a" {"b" 1 "c" 2} 
   "children" [{"a" {"b" 3 "c" 4} "children" []}]}
  {"a" {"b" 5 "c" 6} "children" []}
  {"a" {"b" 7 "c" 8}
    "children" [{"a" {"b" 9 "c" 10} "children" []} {"a" {"b" 10 "c" 10} "children" []}]}]

我正在尝试编写一种算法来在向量中移动元素。例如,在最后一个元素中,它有 children 向量,其中:

"children" [{"a" {"b" 9 "c" 10} "children" []} {"a" {"b" 10 "c" 10} "children" []}]

我的函数应该搜索特定的嵌套地图 - 比方说,找到它的 10 值对应 b 属性 的地图。我会找到 {"a" {"b" 10 "c" 10} "children" []}。找到它后,我需要用矢量更改它的位置。假设 children 将变为:

 "children" [{"a" {"b" 10 "c" 10} "children" []} {"a" {"b" 9 "c" 10} "children" []}]

使用 Zipper,我能够遍历并定位嵌套地图,但不确定如何在矢量内移动它。

我的拉链是这样创建的:

  (z/zipper #(contains? % "children") #(get % "children")  (fn [_ c] c) data-structure)

作为使用 specter 的替代解决方案:

  (def z [
          {"a" {"b" 1 "c" 2}
           "children" [{"a" {"b" 3 "c" 4}
                        "children" []}]}
          {"a" {"b" 5 "c" 6}
           "children" []}
          {"a" {"b" 7 "c" 8}
           "children" [{"a" {"b" 9 "c" 10}
                        "children" []}
                       {"a" {"b" 10 "c" 10}
                        "children" []}]}])


    (transform
      (walker (fn [x]
                (and
                  (vector? x)
                  (some
                    #(= 10
                        (get-in % ["a" "b"]))
                    x))))
      reverse
      z)

Returns:

[{"a" {"b" 1, "c" 2}, "children" [{"a" {"b" 3, "c" 4}, "children" []}]}
 {"a" {"b" 5, "c" 6}, "children" []}
 {"a" {"b" 7, "c" 8},
  "children"
  ({"a" {"b" 10, "c" 10}, "children" []}
   {"a" {"b" 9, "c" 10}, "children" []})}]

备注:

  1. 助行器一直在行走,所以如果您正在寻找一次性转换,您应该以某种方式对其进行调整。我尝试将 FIRST 添加到变换向量,但即使在找到 "b" 之一后它仍然继续行走。
  2. 我尝试使用 collect-one 而不是 get-in 但我没有成功。

如果您找到更好的解决方案,请随时对其进行编辑。我对幽灵还是个新手。

这会做我想做的事:

(defn update-tree [editable? edit loc]
  (loop [loc loc]
    (if (z/end? loc)
    (z/root loc)
    (if (editable? (z/node loc))
      (recur (-> loc z/up (z/edit edit) z/up z/next))
      (recur (z/next loc))))))

但它只适用于这个确切的结构。嵌套更多元素会破坏算法。