This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-07-13
Channels
- # aleph (5)
- # beginners (92)
- # cider (37)
- # cljs-dev (38)
- # cljsjs (2)
- # cljsrn (3)
- # clojure (50)
- # clojure-berlin (1)
- # clojure-canada (3)
- # clojure-dusseldorf (4)
- # clojure-france (1)
- # clojure-germany (1)
- # clojure-italy (7)
- # clojure-nl (21)
- # clojure-spec (2)
- # clojure-uk (106)
- # clojurescript (165)
- # code-reviews (1)
- # community-development (3)
- # cursive (5)
- # datomic (13)
- # editors (12)
- # emacs (3)
- # figwheel-main (141)
- # fulcro (28)
- # graphql (1)
- # immutant (1)
- # jobs (1)
- # jobs-discuss (5)
- # midje (8)
- # nrepl (3)
- # off-topic (28)
- # onyx (4)
- # re-frame (21)
- # reagent (70)
- # ring (2)
- # ring-swagger (9)
- # shadow-cljs (18)
- # spacemacs (6)
- # specter (23)
- # tools-deps (21)
I picked up specter to play with hiccup, and I'm trying to form compound keys by grabbing the keys of sub elements within the data. essentially, given
[[:div.row
[:div.column {:key "A"}]
[:div.column {:key "B"}]]
[:div.row
[:div.culumn {:key "C"}]
[:div.column {:key "D"}]]]
I want
[[:div.row {:key "AB"}
[:div.column {:key "A"}]
[:div.column {:key "B"}]]
[:div.row {:key "CD"}
[:div.culumn {:key "C"}]
[:div.column {:key "D"}]]]
I'll be working on this myself, but if anyone has any ideas, this is effing crazy to write with handrolled clojure, and it seems like the perfect specter magic trick from what I've seen in the videos(def data
[[:div.row
[:div.column {:key "A"}]
[:div.column {:key "B"}]]
[:div.row
[:div.culumn {:key "C"}]
[:div.column {:key "D"}]]])
(transform
[ALL
(collect ALL coll? (nthpath 1) :key)
(before-index 1)]
(fn [keys _] {:key (apply str keys)})
data
)
the cheat sheet is handy for finding navigators you need https://github.com/nathanmarz/specter/wiki/Cheat-Sheet
let me spend a couple hours reverse engineering this. thanks, @nathanmarz
I asked this in the #clojure channel and wondering if specter could be a solution: https://clojurians.slack.com/archives/C03S1KBA2/p1531346207000010
the reason clojure.spec doesn’t work for this case is because spec tries to conform everything. The ebooks I looked at are highly inconsistent. I think what I’m looking for more like a data matcher, rather than a parser
@denik don't understand the output you're looking for
{:class "indent" :content "key lesson 1"}
does not match {:class "indent" :content "key lesson 1"}
and there's no "key lesson 3"
in your input
@nathanmarz start at “START HERE” and match multiple :class
fields, in this case indent
and indent1
but ignore these items before( and after with the stop condition to
)
and you only want to keep items that match the :filter
predicate?
you can do it with specter like this:
(defn start-index [data]
;; fill in
)
(def end-index
(end-fn [data start-index]
;; fill in
))
(select
[(srange-dynamic start-index end-index)
ALL
(selected?
(multi-path
#(= "START HERE" (:class %))
#(= "bl" (:class %))
))
]
data)
but really this is better done with a parser
I'm not very familiar with what spec is capable of, but this is real easy with monadic parser
here’s what that looks like in spec
(require '[clojure.spec.alpha :as s]
'[clojure.pprint :as pp])
(def ebook
[{:class "indent" :content "ignore"}
{:class "indent" :content "ignore"}
{:class "START HERE" :content "Key Lessons"}
{:class "indent" :content "ignore"}
{:class "indent1" :content "ignore"}
{:class "bl" :content "key lesson 1"}
{:class "bl" :content "key lesson 2"}
{:class "indent3" :content "ignore"}])
(s/def
::ebook-tree
(s/and
(s/cat
:ignore (s/* (s/and map? #(= "ignore" (:content %))))
:start (s/and map? #(= (:class %) "START HERE"))
:body (s/* (s/alt
:ignore (s/and map? #(= "ignore" (:content %)))
:item (s/and map? #(= "bl" (:class %)))))
:end (s/and map? #(= "indent3" (:class %))))
(s/conformer
(fn [{:keys [start body]}]
(assoc start :children (for [[tag item] body
:when (not= tag :ignore)]
item))))))
(pp/pprint
(s/conform ::ebook-tree ebook))
with https://github.com/nathanmarz/specter/issues/236 you could do it more easily with specter
@nathanmarz I think that’s exactly what I’m looking for.