redplanetlabs / specter

Clojure(Script)'s missing piece
Apache License 2.0
2.51k stars 102 forks source link

Remove all leaves that don't match a predicate #314

Closed WhittlesJr closed 2 years ago

WhittlesJr commented 2 years ago

I'm trying to remove leaves of a structure that don't match a predicate. I seemingly can't just setval to NONE with a walker matching on (not (pred x)), because that also selects branches that don't match the predicate, and leaves me with an empty collection.

It would be ideal if I could somehow get the complement of a selection. Then I could use a walker on the pred, select everything not matched, and setval that stuff to NONE.

WhittlesJr commented 2 years ago

I would think that (not (pred x)) should work, because it's depth-first... but the result is that the whole collection is transformed into sp/NONE .

If I just do (setval (walker #(pred %)) NONE m), it does remove the things that positively match. But I can't reverse that to keep the things that match.

WhittlesJr commented 2 years ago

Oh, I understand why it fails with not, despite being depth-first. It navigates past the value to its parent key, and sets that to NONE.

nathanmarz commented 2 years ago

That's correct. I suggest making a custom recursive-path to have exact control.