8

可能重复:
如何仅返回真实值作为映射操作的结果

我有一个包含虚假和真实值的集合。我只想计算真实值,有没有办法做到这一点?

(计数 (1 2 3 nil nil)) => 5

4

5 回答 5

23

如果你想保持真实值只需要使用identity函数:

   (count (filter identity '(1 2 3 nil nil false true))) 
于 2012-09-20T19:07:30.183 回答
8

我建议使用 reduce 执行此操作,如下所示:

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

以这种方式使用reduce的原因:

  • 它可能会更高效,并将受益于 Clojure 的新 reducers 功能,该功能可以在许多集合上实现事实归约
  • 它避免了创建中间序列(如果您使用像过滤器这样的惰性序列函数会发生这种情况)

如果您已经有一个已实现的序列,那么以下也是一个不错的选择,因为它将受益于循环中的原始算术:

(defn count-truthy [coll]
  (loop [s (seq coll) cnt 0]
    (if s
      (recur (next s) (if (first s) (inc cnt) cnt))
      cnt)))
于 2012-09-21T00:38:24.023 回答
3

只需删除您不想计算的值。

(count (remove nil? [1 2 3 nil nil])) => 3
于 2012-09-20T18:09:16.213 回答
2
(defn truthy-count [coll] 
   (reduce + 0 
     (map #(if % 1 0) coll)))

虽然我承认我更喜欢 dAni 的解决方案。

于 2012-09-20T19:28:47.950 回答
2

一般模式是过滤序列并计算结果

(count (filter #(if % %) [1 2 3 nil nil false]))
3 

#(if % %)只是对真实性的简短测试,仅当项目为真实或虚假(nil)时才返回项目

于 2012-09-20T20:10:47.480 回答