Можно ли написать универсальный алгоритм для обновления элемента во вложенной (независимо от того, насколько вложенной) структуре данных с помощью Zippers?
На прошлой неделе я пытался написать алгоритм с Zippers для обновления определенного элемента во вложенной структуре данных. Как переместить элемент в структуре, возможно, с помощью Zippers?
Мой ответ там решает проблему для этой точной структуры, вложение большего количества элементов нарушает алгоритм.
Это заставило задуматься, возможно ли написать общий алгоритм с помощью Zippers для обновления определенных данных во вложенной структуре данных (независимо от того, насколько они вложены)? Или молнии только тогда, когда вы точно знаете свои шаги?
Мне нужно понять, что правильно я пытаюсь заставить Молнии делать что-то, что не предназначено для Молний.
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"
"!"]}
Конечно, вы также можете использовать простую ходьбу для выполнения схожих задач, примером чего является этот вопрос о переходных картах.
Chiron
Взгляните на data.zip, так как он предоставляет возможность связывать предикаты, чтобы получать все интересующие записи, а также обновлять узлы.