Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

counting only truthy values in a collection [duplicate]

Tags:

clojure

Possible Duplicate:
how to return only truthy values as the result of a map operation

I have a collection which has falsy and truthy values. I would like to only count the truthy values, is there a way to do that ?

(count (1 2 3 nil nil)) => 5

like image 352
murtaza52 Avatar asked Sep 20 '12 18:09

murtaza52


4 Answers

If you want to keep the truthy values just need to use the identity function:

   (count (filter identity '(1 2 3 nil nil false true))) 
like image 99
DanLebrero Avatar answered Sep 19 '22 01:09

DanLebrero


I would recommend doing this with reduce as follows:

(defn count-truthy [coll]
  (reduce (fn [cnt val] (if val (inc cnt) cnt)) 0 coll))

Reasons for using reduce in this way:

  • It is likely to be more efficient, and will benefit from Clojure's new reducers functionality that enables fact reduces on many collections
  • It avoids creating an intermediate sequence (which would happen if you used a lazy sequence function like filter)

If you already have a realised sequence, then the following is also a good option, as it will benefit from primitive arithmetic in the loop:

(defn count-truthy [coll]
  (loop [s (seq coll) cnt 0]
    (if s
      (recur (next s) (if (first s) (inc cnt) cnt))
      cnt)))
like image 25
mikera Avatar answered Sep 22 '22 01:09

mikera


Just remove values that you do not want to count.

(count (remove nil? [1 2 3 nil nil])) => 3
like image 24
mishadoff Avatar answered Sep 23 '22 01:09

mishadoff


(defn truthy-count [coll] 
   (reduce + 0 
     (map #(if % 1 0) coll)))

Although I admit I like dAni's solution better.

like image 21
noahlz Avatar answered Sep 19 '22 01:09

noahlz