Fork me on GitHub
#specter
<
2024-01-31
>
wei18:01:06

I'm trying to transform something like this:

(def -TAGS_BY_GROUP
  {:tag-group-1 [{:id "id-1" :label "Tag 1A"}
                 {:id "id-2" :label "Tag 1B"}
                 {:id "id-3" :label "Tag 1C"}]
   :tag-group-2 [{:id "id-4" :label "Tag 2A"}
                 {:id "id-5" :label "Tag 2B"}]
   :tag-group-3 [{:id "id-6" :label "Tag 3A"}
                 {:id "id-7" :label "Tag 3B"}
                 {:id "id-8" :label "Tag 3C"}]})
into this (an index)
{"id-1" {:id "id-1" :label "Tag 1A"},
 "id-2" {:id "id-2" :label "Tag 1B"},
 "id-3" {:id "id-3" :label "Tag 1C"},
 "id-4" {:id "id-4" :label "Tag 2A"},
 "id-5" {:id "id-5" :label "Tag 2B"},
 "id-6" {:id "id-6" :label "Tag 3A"},
 "id-7" {:id "id-7" :label "Tag 3B"},
 "id-8" {:id "id-8" :label "Tag 3C"}}
here's my half-specter solution:
(->> (sp/select [sp/MAP-VALS sp/ALL] -TAGS_BY_GROUP)
     (map (juxt :id identity))
     (into {}))
what would be the idiomatic specter way to do it?

J19:01:43

Something like this:

(into {} (sp/traverse [sp/MAP-VALS sp/ALL (sp/collect-one :id)] tags-by-group)

🙏 1
wei19:01:51

thanks! why does collect-one not just result in a list of ids? also, when do you use traverse vs select?

nathanmarz01:02:14

traverse is more efficient when being fed into a reduce

👍 1
wei07:02:01

i see, collect-one adds an arg, so the transforming function gets the both the collected value and the original one

👍 1