Fork me on GitHub
#specter
<
2017-07-19
>
slpssm15:07:41

Hi, I’m new to specter and have a select I keep trying to do but I’m not quite sure how. I have data like this:

{:foo [{:data "text" :required true}]
 :bar [{:data "text"}]
 :baz [{:data "text" :required true}]}
and I’d like the list of keys whose value has :required in the inner map. This seems to do it:
(map first (s/select [s/ALL (fn[[k,v]] (:required (first v)))] data))
and return the expected
(:foo :baz)
Is there a better way? There have been a few places where I’d like the outer key depending on some value lower in the data structure.

nathanmarz15:07:38

@slpssm can those inner vectors have multiple elements?

nathanmarz15:07:04

if so then it's (select [ALL (selected? LAST ALL (must :required)) FIRST] data)

nathanmarz15:07:55

otherwise it's (select [ALL (selected? LAST FIRST (must :required)) FIRST] data) to match your code

nathanmarz15:07:17

this code just checks for existence of a :required key, if you need to match only when :required is truthy replace (must :required) with :required identity

slpssm15:07:21

I think it can have more than one item, but I’ve never seen one so I’m going with the first version. 🙂 With a note on the second version just in case. Now I just need to parse this so I know how it works.

nathanmarz15:07:56

selected? is a filter based on whether the subpath selects at least a single value

slpssm15:07:27

LAST gets you into the array, the next ALL looks at key/values, (must :required) does the :required check and the last FIRST is the outer key. About right?

nathanmarz15:07:14

the initial LAST goes to the value for that key/value pair, the subsequent ALL looks at all maps inside that vector

slpssm15:07:26

Ah, OK. Yes. FIRST would be the key, LAST is the value.