J'ai besoin de modifier dynamiquement les données de cette structure:Clojure prewalk récursion infinie pour les requêtes datomic
[:db/id
:list/title
:list/type
{:list/items [... lots of nested data ...]}]
à ce qui suit:
[:db/id
:list/title
:list/type
{(default :list/items []) [... lots of nested data ...]}]
Depuis que je me occupe plusieurs requêtes différentes, je peux être Assurez-vous que la jointure sera le quatrième élément du vecteur. Mais j'ai besoin de remplacer chaque instance de :list/items
par (default :list/items [])
.
La seule façon que je sais de faire ceci est en utilisant clojure.walk/prewalk
. Cependant, elle conduit à une récursion infinie:
(clojure.walk/prewalk #(if (= :list/items %)
'(default :list/items [])
%)
query)
Une fois que la promenade trouve :list/items
et le remplace par '(default :list/items [])
, il trouve alors la :list/items
de la valeur remplacée, et remplace celle. Et ainsi de suite.
Je peux utiliser un atome pour m'assurer que la valeur n'est remplacée qu'une seule fois, mais cela ressemble à de la triche.
D'autres approches?
Oh, nice, postwalk-replace est parfait. Par curiosité, disons que je devais utiliser prewalk pour manipuler la requête d'une autre manière. Aurais-je besoin d'utiliser un atome pour suivre le remplacement? Ou y a-t-il un autre moyen? – egracer
de quelle façon voulez-vous dire exactement? Je ne peux pas y penser tout de suite) – leetwinski
mais je vous proposerais de jeter un coup d'œil aux 'zippers' pour ça. Si vous voulez un contrôle précis sur le remplacement et l'itération sur l'arbre. Par exemple, il vous permet de remplacer un élément, puis d'ignorer cet élément, ou de le suivre dans certains accumulateurs (puisque les fermetures à glissière fonctionnent bien avec 'loop/recur' – leetwinski