Clojure 仅计算集合中的真实值

Clojure 仅计算集合中的真实值,clojure,Clojure,可能重复: 我有一个收藏,有虚假和真实的价值观。我只想计算真实的价值观,有没有办法做到这一点 (计数(1 2 3零零零))=>5 只需删除您不想计算的值 (count (remove nil? [1 2 3 nil nil])) => 3 如果要保留真实值,只需使用identity功能: (count (filter identity '(1 2 3 nil nil false true))) 虽然我承认我更喜欢dAni的解决方案。一般模式是过滤序列并计算结果 (count

可能重复:

我有一个收藏,有虚假和真实的价值观。我只想计算真实的价值观,有没有办法做到这一点

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


只需删除您不想计算的值

(count (remove nil? [1 2 3 nil nil])) => 3

如果要保留真实值,只需使用
identity
功能:

   (count (filter identity '(1 2 3 nil nil false true))) 

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

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

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

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

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

(defn count-truthy [coll]
  (reduce (fn [cnt val] (if val (inc cnt) cnt)) 0 coll))
以这种方式使用reduce的原因:

  • 它可能会更高效,并将受益于Clojure的新reducers功能,该功能可在许多集合上实现事实还原
  • 它避免了创建一个中间序列(如果您使用像filter这样的惰性序列函数,就会发生这种情况)
如果已经实现了序列,那么以下也是一个不错的选择,因为它将受益于循环中的基本算法:

(defn count-truthy [coll]
  (loop [s (seq coll) cnt 0]
    (if s
      (recur (next s) (if (first s) (inc cnt) cnt))
      cnt)))

轻微错误:(count(remove nil?[1 2 3 nil nil false])=>4您可以通过将
nil?
替换为
#(如果%false-true)
#(如果%false-true)来修复此问题,它绝对等同于函数not。(count(remove not[1 2 3 nil nil false])返回正确的结果。与
(count(filter)(identity
方法)相比,这有什么好处(如果有的话)?这只是表达“如果该项是真实的”概念的一种不同方式就我个人而言,我发现这一点更加清楚,尽管这只是我的观点——不重复计数值与返回值是不同的操作(并且有一些完全不同的解决方案)
(defn count-truthy [coll]
  (loop [s (seq coll) cnt 0]
    (if s
      (recur (next s) (if (first s) (inc cnt) cnt))
      cnt)))