Considering a new function for clojure core: classify

137 views
Skip to first unread message

Ricardo Acuna

unread,
Nov 7, 2015, 1:04:39 PM11/7/15
to Clojure Dev
This is the function in question:

(defn classify
[pred coll]
[(filterv pred) (filterv (complement pred))])

The rationale is that often you're interested in the whole collection, but you want to know whether the individual items satisfy a predicate. For instance.

(let [[yes no] (classify awesome-type-or-java-class-instance? coll]
(if (empty? no)
yes
(do-something-that-gets-everything-into-yes no))

Or a more concrete example in a function I recently built:

(defn tree
([^String path]
(when-some [paths (ls path)]
(let [[file-tree dirs] (classify (or file? map?) paths)]
(if (empty? dirs)
file-tree
(tree file-tree dirs)))))
([^PersistentVector file-tree ^PersistentVector dirs]
(letfn [(x-form [acc dir]
(let [path (.toString dir)]
(conj acc {path (tree path)})))]
(reduce x-form file-tree dirs))))

Andy Fingerhut

unread,
Nov 7, 2015, 1:10:23 PM11/7/15
to cloju...@googlegroups.com
To clojure-dev: My apologies, I allowed this posting from Ricardo without first double-checking that he had signed the Clojure CA.  He has not.  Ricardo, I will send you a separate private message with instructions for joining Clojure Dev, and a pointer to the Clojure Google group, where anyone can join.

Regarding your question, Ricardo, I think group-by does nearly exactly what you want, if the predicate function always returns true or false:

user=> (group-by even? [0 1 2 3 4 5 6 7])
{true [0 2 4 6], false [1 3 5 7]}

If it doesn't, you can wrap your function in a call to boolean, e.g. (boolean (pred x)), to convert its logical truthy or falsey value to true or false.

Andy



--
You received this message because you are subscribed to the Google Groups "Clojure Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to clojure-dev...@googlegroups.com.
To post to this group, send email to cloju...@googlegroups.com.
Visit this group at http://groups.google.com/group/clojure-dev.
For more options, visit https://groups.google.com/d/optout.

Gary Trakhman

unread,
Nov 7, 2015, 1:12:44 PM11/7/15
to cloju...@googlegroups.com
This is also an old pattern that does essentially the same thing: ((juxt filter remove) pred coll)

Alex Miller

unread,
Nov 9, 2015, 3:40:11 PM11/9/15
to Clojure Dev
The downside of the juxt version is that it will walk the coll twice. 

Gary Fredericks

unread,
Nov 9, 2015, 5:25:21 PM11/9/15
to cloju...@googlegroups.com
Related, split-at and split-with currently take a similar approach, and split-with will call the pred twice on the left part of the sequence.
--
Reply all
Reply to author
Forward
0 new messages