Это можно легко сделать с помощью библиотеки Tupelo Forest:
(dotest
(with-forest (new-forest)
(let [edn-orig [1 [[2] 3]]
root-hid (add-tree (edn->tree edn-orig))
hid (find-hid root-hid [::tf/list ::tf/list])
subtree-edn-orig (-> hid hid->tree tree->edn)
>> (kids-update hid butlast)
subtree-edn-final (-> hid hid->tree tree->edn)
edn-final (-> root-hid hid->tree tree->edn)]
(is= subtree-edn-orig [[2] 3])
(is= subtree-edn-final [[2]])
(is= edn-final [1 [[2]]] ))))
В созданном дереве есть узлы со :tag
значениями :tupelo.forest/list
на первом и втором уровнях:
(is= (hid->bush root-hid)
[{:tag :tupelo.forest/list, :tupelo.forest/index nil}
[#:tupelo.forest{:value 1, :index 0}]
[{:tag :tupelo.forest/list, :tupelo.forest/index 1}
[{:tag :tupelo.forest/list, :tupelo.forest/index 0}
[#:tupelo.forest{:value 2, :index 0}]]]] )
HID - это указатель на узел дерева, поэтому root-hid
указывает на корневой узел дерева, а hid
указывает на поддерево [[2] 3]
. После удаления самого правого узла 3
, hid
указывает на поддерево [[2]]
.
Для дочерних узлов (kids
) мы используем функцию butlast
, чтобы удалить самые правые, а затем преобразовать данные из формата леса / дерева обратно в EDN.
См. README здесь , а API документы здесь . Здесь также есть много примеров реального кода . Также смотрите Clojure Conj видео .