Можно ли написать общий алгоритм для обновления элемента во вложенной (независимо от того, насколько вложенной) структуре данных с помощью Zipper?

На прошлой неделе я пытался написать алгоритм с Zippers для обновления определенного элемента во вложенной структуре данных, Как переместить элемент внутри структуры, возможно, с помощью молнии?

Мой ответ решает проблему для этой точной структуры, вложение большего количества элементов нарушает алгоритм.

Это заставило задуматься, можно ли написать общий алгоритм с Zippers для обновления определенных данных во вложенной структуре данных (независимо от того, насколько она вложена)? Или молнии только тогда, когда вы точно знаете свои шаги?

Мне нужно понять, что я пытаюсь заставить молнии делать что-то, для чего они не созданы.


person Chiron    schedule 24.08.2015    source источник


Ответы (2)


Вы можете использовать молнии таким образом, так как вы можете перемещать молнию в любом направлении по вашему выбору. В качестве примера взгляните на библиотеку zip-visit, которая предлагает произвольное посещение через застежки-молнии, с возможностью смены узлов по мере необходимости.

Пример взят из документации:

(def s "<div><span id='greeting'>Hello</span> <span id='name'>Mr. Foo</span>!</div>")
(def root (z/xml-zip (xml/parse (java.io.ByteArrayInputStream. (.getBytes s)))))

(defn replace-element [id replacement]
  (visitor :pre [n s]
    (if (= (:id (:attrs n)) id) {:node replacement})))

user=> (pprint (:node (visit root nil [(replace-element "name" "Mr. Smith")])))
{:tag :div,
 :attrs nil,
 :content
 [{:tag :span, :attrs {:id "greeting"}, :content ["Hello"]}
  "Mr. Smith"
  "!"]}

Конечно, вы также можете использовать простую прогулку для выполнения аналогичных задач, пример которых находится на этот SO вопрос по обходу карт.

person Mark Fisher    schedule 24.08.2015

Хирон

Взгляните на data.zip, так как он предоставляет возможность связывать предикаты для получения всех записей интерес, а также обновления узлов.

person Frank C.    schedule 25.08.2015