Skip to content

Instantly share code, notes, and snippets.

@Jannis
Created February 18, 2016 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jannis/e30374115f1065edea11 to your computer and use it in GitHub Desktop.
Save Jannis/e30374115f1065edea11 to your computer and use it in GitHub Desktop.
;; Transducer to transform
;;
;; [user [name email] foo bar [baz]]
;;
;; into
;;
;; [[user [name email]] [foo nil] [bar [baz]]]
;;
;; when transducing like this:
;;
;; (transduce (collect-prop-pairs) conj [] '[user [name email] foo bar [baz]])
(defn collect-prop-pairs
[]
(fn [rf]
(let [pair (volatile! [])]
(letfn [(flush-pair [result]
(let [values @pair]
(assert (or (empty? values)
(and (= (count values) 1)
(or (symbol? (values 0))
(map? (values 0))))
(and (= (count values) 2)
(or (symbol? (values 0))
(map? (values 0)))
(vector? (values 1)))))
(if (empty? values)
result
(do
(vreset! pair [])
(rf result (cond-> values
(= 1 (count values))
(conj nil)))))))]
(fn
([] (rf))
([result]
(let [result (rf (flush-pair result))]
;; `(~'cljs.core/ensure-reduced result)
result))
([result input]
(cond
(vector? input)
(do
(vswap! pair conj input)
(flush-pair result))
(or (symbol? input) (map? input))
(do
(let [result (flush-pair result)]
(vreset! pair [input])
result)))))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment