Hi, Am 19.10.2009 um 01:34 schrieb Dmitry Kakurin:
> This is in line with what I was thinking for my own custom filter
> function.
> Now how would you modify it if the same record can be both "sales" and
> "upgrade" at the same time?
> I.e. if filters are not mutually exclusive.
I'd define a helper. (Code untested)
(defmacro ->if
"Acts like ->, but pipes the expression only through the next step
if the predicate clause returns true. Otherwise it skips the step
going on with the next steps, if any."
([x] x)
([x pred form & forms]
(let [x-gs (gensym "x")]
`(let [~x-gs ~x]
(if (-> ~x-gs ~pred)
(-> ~x-gs form (->if ~...@forms))
(->if ~x-gs ~...@forms))))))
(letfn [(add-sale
[[sales upgrades demos] x]
[(conj sales x) upgrades demos])
(add-upgrade
[[sales upgrades demos] x]
[sales (conj upgrades x) demos])
(add-demo
[[sales upgrades demos] x]
[sales upgrades (conj demos x)])]
(reduce (fn [sales-upgrades-demos data]
(->if sales-ugprades-demos
(do (is-sales? data)) (add-sale data)
(do (is-upgrade? data)) (add-upgrade data)
(do (is-demo? data)) (add-demo data)))
[[] [] []] (get-idata)))
This is maybe trying to be a little too clever, but well... I found
something like ->if useful at times. Note that, the predicate there
normally depends on the thing piped through the chain with ->. However
in our case it is not. That's what's the do is for: to ignore the
argument of the ->.
Looking at this, I would think, that the other approaches using the
group are much more elegant.
Hmm.. Another approach might be juxt:
(defn conj-if
"Conjoins x to coll if x fulfills pred."
[pred coll x]
(if (pred x)
(conj coll x)
coll))
(reduce (juxt #(conj-if is-sales? (nth %1 0) %2)
#(conj-if is-upgrade? (nth %1 1) %2)
#(conj-if is-demo? (nth %1 2) %2))
[[] [] []] (get-idata))
This looks much nicer, although there is still the ugly nth
"destructuring" for vector. And juxt is maybe only semi-official API
at the moment... If you don't want to depend on contrib, this might be
an alternative, though...
Sincerely
Meikel
smime.p7s
Description: S/MIME cryptographic signature
