specter

Latest version: 1.1.3
dominicm 2019-03-19T13:22:05.038100Z

How can I query a data structure like so:

{:a 1
 :b {:a 2}}
Where I want to find all :a maps? I tried walker but it stops when it finds a match, and I also tried:
(select
    [(specter/recursive-path [] p
                             (specter/cond-path
                               coll? [specter/VAL [specter/ALL p]]
                               :else specter/STAY)))
     ]
)
But it didn't finish, and I think that's because it was recursing into the VAL

dominicm 2019-03-19T13:28:16.038800Z

It might not finish because it was trying to print such a massive value, actually. My bad 🙂 I can't seem to filter the results like I want to though.

idiomancy 2019-03-19T16:05:21.041400Z

so, when you say that you want all :a maps, do you mean you want to traverse the entire tree and get all the values for any :a keys in any nested substructure or you only want to descend the :a branches to look for sub values?

idiomancy 2019-03-19T16:05:50.042Z

err, what is the intended output with input {:a 1 :b {:a 2}}

idiomancy 2019-03-19T16:26:54.042700Z

are :a values always terminal? can you have {:a {:a 5}}?

idiomancy 2019-03-19T16:29:56.043300Z

@dominicm

(spr/select [(spr/stay-then-continue spr/MAP-VALS) (spr/must :a)] {:a 1 :b {:a 2}})
=> [1 2]

dominicm 2019-03-19T16:44:07.044100Z

@idiomancy I'm interested in the map itself, rather than the values. I want to traverse the entire tree and get all the values with an :a key.

idiomancy 2019-03-19T16:49:37.045200Z

is my solution giving you the correct answer?

idiomancy 2019-03-19T16:49:46.045400Z

I crave validation

dominicm 2019-03-19T16:56:25.046Z

@idiomancy for my particular data structure, just running the stay-then-continue gives me:

clojure.lang.PersistentHashMap cannot be cast to java.util.Map$Entry     
:thinking_face:

idiomancy 2019-03-19T16:57:30.047Z

in the actual operation are you doing, like (map #(select [...] %) yourData) ?

dominicm 2019-03-19T16:58:49.047400Z

Nope, but my data is a list

idiomancy 2019-03-19T16:59:13.047900Z

is it a list of maps or a list of lists?

dominicm 2019-03-19T17:00:01.048700Z

Oh, I realize I've probably neglected something important. While it is a list of maps, those maps might look like:

{:a 1
 :b [{:a 2}]}

idiomancy 2019-03-19T17:00:52.048900Z

hahaha oh-ho!

idiomancy 2019-03-19T17:00:57.049100Z

well then

idiomancy 2019-03-19T17:01:21.049400Z

yes, mapvals will blow up there

idiomancy 2019-03-19T17:14:17.050200Z

@dominicm

(def dominicm-selector
    (spr/recursive-path [desired-key] p
                        (spr/cond-path
                          sequential? [spr/ALL p]
                          map? [(spr/stay-then-continue [spr/MAP-VALS p])
                                (spr/must desired-key)]
                          :else spr/STAY)))

(spr/select (dominicm-selector :a) [{:a 1 :b [{:a {:a 4}}]}])
=> [1 4]

dominicm 2019-03-19T17:27:54.051100Z

@idiomancy that's returning a much smaller list than I expected :thinking_face:

idiomancy 2019-03-19T17:34:08.052300Z

I also realize that else branch is unnecessary, I assume all lists only contain maps right? because I realize that selector will also catch any values in lists that aren't maps

dominicm 2019-03-19T17:34:28.052700Z

Nope 😄 lists can contain anything

dominicm 2019-03-19T17:34:42.053100Z

this is a massive data structure, and I'm trying to pull out just the bits that I'm interested in.

idiomancy 2019-03-19T17:35:41.053700Z

hahah hmm