问题
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
回答1:
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)))
回答2:
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)))
回答3:
Just remove values that you do not want to count.
(count (remove nil? [1 2 3 nil nil])) => 3
回答4:
(defn truthy-count [coll]
(reduce + 0
(map #(if % 1 0) coll)))
Although I admit I like dAni's solution better.
回答5:
the genral pattern is filter the sequence and count the results
(count (filter #(if % %) [1 2 3 nil nil false]))
3
the #(if % %)
is just a short test for truthyness that returns an item only if it is truthy or something falsy (nil) otherwise
来源:https://stackoverflow.com/questions/12518320/counting-only-truthy-values-in-a-collection