Fork me on GitHub
#specter
<
2022-05-17
>
Matthew Davidson (kingmob)09:05:48

OK, I’m trying Specter out, and I can’t figure out how to make this transform happen. I’ve got a two-level map containing some vecs of numbers, and I want to replace the middle level with the set intersection of the vecs. How do I make:

(def example {"top1" {"mid1" [1 2 3]
                      "mid2" [2 3 4]
                      "mid3" [3 4 5]}
              "top2" {"mid4" [1 2 3]
                      "mid5" [2 3 4]
                      "mid6" [3 4 5]}})
turn into something like:
{"top1" #{3}
 "top2" #{3}}
?

Matthew Davidson (kingmob)09:05:59

And how would I filter out some of the “mid*” keys if necessary?

Matthew Davidson (kingmob)09:05:18

Closest I’ve come so far is something like:

(transform [MAP-VALS]
           (fn [m]
             (->> m
                  (select MAP-VALS)
                  (reduce (fn rf [s v]
                            (set/intersection (set s) (set v))))))
           example)
but it takes two stages and feels un-Specter-y

Lucy Wang02:07:34

my 2c:

(defn shrink-inner-map [m]
    (->> m
         (sp/select [sp/MAP-VALS (sp/view set)])
         (apply clojure.set/intersection)
         ))

  (sp/transform [sp/MAP-VALS] shrink-inner-map example)

isak18:05:46

(transform
  [MAP-VALS (collect MAP-VALS (view set))]
  (fn [sets _] (apply set/intersection sets))
  example)
@kingmob ^ A little more spectery, I think, but maybe someone can do better.