Fork me on GitHub
#specter
<
2021-07-28
>
richiardiandrea21:07:19

Hi there, say I have maps that can look like this {:foos [{:xx 1} {:yy 2] :bar "BAR"} {:foos [#uuid "xx" #uuid "yy"] :bar "BAR"} {:foos [{} {}] :bar "BAR"} How can I trim the :foos if "empty" in specter?

richiardiandrea21:07:23

tried [(sp/must :foos) (sp/pred #(every? empty? %)) (sp/terminal sp/NONE)] but it throws in case of #uuid

isak22:07:58

@richiardiandrea you should just check for map? first in that pred. Example:

(let [xs [{:foos [{:xx 1} {:yy 2}] :bar "BAR"}
            {:foos [#uuid "123e4567-e89b-12d3-a456-426652340000" #uuid "123e4567-e89b-12d3-a456-426652340010"] :bar "BAR"}
            {:foos [{} {}] :bar "BAR"}]]
    (sp/setval 
      [sp/ALL (sp/must :foos) (sp/pred #(every? (fn [x] (and (map? x) (empty? x))) %))]
      sp/NONE
      xs))

=> [{:foos [{:xx 1} {:yy 2}], :bar "BAR"}
 {:foos [#uuid"123e4567-e89b-12d3-a456-426652340000" #uuid"123e4567-e89b-12d3-a456-426652340010"], :bar "BAR"}
 {:bar "BAR"}]

richiardiandrea22:07:03

oh ok that makes sense - I was thinking there would be more specter magic I was missing instead

isak22:07:26

This may be better, but depends what you are trying to do (adapted from a similar thing I needed):

(def rec-node-path
    (sp/recursive-path
      [] p
      (sp/cond-path 
        map? (sp/continue-then-stay sp/MAP-VALS p)
        vector? (sp/continue-then-stay sp/ALL p))))

  (let [xs [{:foos [{:xx 1} {:yy 2}] :bar "BAR"}
            {:foos [#uuid "123e4567-e89b-12d3-a456-426652340000" #uuid "123e4567-e89b-12d3-a456-426652340010"] :bar "BAR"}
            {:foos [{} {}] :bar "BAR"}]]
    (sp/setval [sp/ALL :foos rec-node-path empty?] sp/NONE xs))