Question for the specter experts, I have a data structure like
{:roots {:query :Query},
:objects
{:Query
{:fields
{:ping {:type (non-null :Status)},
:getList {:type (list (non-null String))},
:getListError {:type (list (non-null String))},
:introspection {:type String},
:error {:type String},
:shouldBeHidden
{:type (non-null String),
:directives [{:directive-type :hidden}]}}},
:Status {:fields {:pong {:type (non-null String)}}},
:ShouldIgnore
{:fields {:f1 {:type String}},
:directives [{:directive-type :hidden}]}}}
And I want to filter out all the keys/values where the value contains {:directives {:directive-type :hidden}}
So after filtering that map should become
{:roots {:query :Query},
:objects
{:Query
{:fields
{:ping {:type (non-null :Status)},
:getList {:type (list (non-null String))},
:getListError {:type (list (non-null String))},
:introspection {:type String},
:error {:type String},}},
:Status {:fields {:pong {:type (non-null String)}}}}}
I got it working with a fixed depth, but the thing to hide can be either on 3rd or 4th level of nesting, I can't understand how to make that workI've done something similar to
(defn non-hidden-leaf?
[v]
(when-not (-> v
:directives
set
(contains? {:directive-type :hidden}))
v))
(defn filter-hidden
[v]
(->> v
(sp/transform [sp/MAP-VALS] non-hidden-leaf?)
(sp/transform [sp/ALL] #(if (nil? %) sp/NONE %))))you can use MAP-NODES from the wiki: https://github.com/redplanetlabs/specter/wiki/Using-Specter-Recursively#recursively-navigate-to-every-map-in-a-map-of-maps
(sp/transform [MAP-NODES sp/MAP-VALS] non-hidden-leaf?)
also why not use NONE directly in non-hidden-leaf? ?
(defn non-hidden-leaf?
[v]
(if (-> v
:directives
set
(contains? {:directive-type :hidden}))
sp/NONE
v))ah yeah I think I tried to use NONE directly but didn't work
I can try again
let me know if it worked
unrelated: clojure convention is that functions ending with ? return a boolean value
ah yeah it was returning a boolean, I haven't updated it after I changed it
does this require a recursive transformation, or are you always looking at the top-level fields of each item under :objects?
The thing to hide could be either in objects or in fields
So two different depths
in that case, I wouldn't use a recursive path but would explicitly target what you want to remove
(setval [:objects
MAP-VALS
(multi-path [:fields MAP-VALS]
STAY)
map?
(selected?
:directives
ALL
:directive-type
(pred= :hidden))]
NONE
data)ah brilliant that works