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 nils beforehand instead of creating case see above.

another - conceptually similar - solution use multimethods.


Comments

Popular posts from this blog

php - Permission denied. Laravel linux server -

google bigquery - Delta between query execution time and Java query call to finish -

python - Pandas two dataframes multiplication? -