How to test in Clojure if any given value is not-empty collection? -
i need predicate returns logically true if given value not-empty collection , logically false if it's else (number, string etc.). , more specifically, predicate won't throw illegalargumentexception
if applied single number, or string.
i came following function, i'm wondering if there more idiomatic approach?
(defn not-empty-coll? [x] (and (coll? x) (seq x)))
this satisfy following tests:
(is (not (not-empty-coll? nil))) ;; -> false (is (not (not-empty-coll? 1))) ;; -> false (is (not (not-empty-coll? "foo"))) ;; -> false (is (not (not-empty-coll? []))) ;; -> nil (false) (is (not (not-empty-coll? '()))) ;; -> nil (false) (is (not (not-empty-coll? {}))) ;; -> nil (false) (is (not-empty-coll? [1])) ;; -> (1) (true) (is (not-empty-coll? '(1))) ;; -> (1) (true) (is (not-empty-coll? {:a 1})) ;; -> ([:a 1]) (true)
edit: potential use case:
let's need process raw external data not (yet) under our control. input example collection contains either primitive values, or nested collections. other example collection holding inconsistent (maybe broken?) tree structure. so, can consider mentioned predicate first line data cleaning.
otherwise, agree comments better explicitly separate , process collection , non-collection data.
how using clojure protocols , type extensions solve this?
(defprotocol emptycollpred (not-empty-coll? [this])) (extend-protocol emptycollpred object (not-empty-coll? [this] false) nil (not-empty-coll? [this] false) clojure.lang.seqable (not-empty-coll? [this] (not (empty? (seq this))))) (is (not (not-empty-coll? nil))) ;; -> false (is (not (not-empty-coll? 1))) ;; -> false (is (not (not-empty-coll? "foo"))) ;; -> false (is (not (not-empty-coll? []))) ;; -> nil (false) (is (not (not-empty-coll? '()))) ;; -> nil (false) (is (not (not-empty-coll? {}))) ;; -> nil (false) (is (not-empty-coll? [1])) ;; -> (1) (true) (is (not-empty-coll? '(1))) ;; -> (1) (true) (is (not-empty-coll? {:a 1})) ;; -> ([:a 1]) (true)
maybe cleaner extend string
, number
instead of object
- depends on know incoming data. also, better filter out nil
s beforehand instead of creating case see above.
another - conceptually similar - solution use multimethods.
Comments
Post a Comment