2012-09-20 41 views
7

thể trùng lặp:
how to return only truthy values as the result of a map operationđếm giá trị chỉ truthy trong một bộ sưu tập

Tôi có một bộ sưu tập có giá trị falsy và truthy. Tôi chỉ muốn đếm các giá trị trung thực, có cách nào để làm điều đó không?

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

+2

không phải là một trùng lặp - đếm giá trị so với trả lại chúng là một hoạt động khác nhau (và có một số giải pháp khá khác nhau) – mikera

Trả lời

19

Nếu bạn muốn giữ lại các giá trị truthy chỉ cần sử dụng chức năng identity:

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

Câu trả lời này thật tuyệt! – murtaza52

3

Chỉ cần loại bỏ các giá trị mà bạn không muốn đếm.

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

lỗi nhỏ: (đếm (loại bỏ nil? [1 2 3 nil nil false])) => 4 –

+0

bạn có thể sửa lỗi này bằng cách thay thế 'nil? 'Bằng' # (nếu% false true) ' –

+2

# (nếu% false true) hoàn toàn tương đương với hàm không . (đếm (loại bỏ không [1 2 3 nil nil false])) trả về kết quả chính xác. – animal

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

Mặc dù tôi thừa nhận tôi thích giải pháp Dani tốt hơn.

2

mô hình genral là lọc các chuỗi và đếm kết quả

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

các #(if % %) chỉ là một bài kiểm tra ngắn cho truthyness trả về một mục duy nhất nếu nó là truthy hoặc một cái gì đó falsy (nil) khác

+0

Điều gì có lợi thế này, nếu có, trên '(đếm (cách tiếp cận bộ lọc (nhận dạng)? – noahlz

+0

nó chỉ là một cách khác để thể hiện khái niệm" nếu mục này là sự thật "cá nhân tôi thấy nó rõ ràng hơn mặc dù đó chỉ là của tôi ý kiến –

6

tôi sẽ khuyên bạn nên làm điều này với giảm như sau:

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

lý do cho việc sử dụng giảm theo cách này:

  • Nó có khả năng là hiệu quả hơn, và sẽ được hưởng lợi từ chức năng gia giảm mới Clojure của cho phép thực tế giảm trên nhiều bộ sưu tập
  • Nó tránh tạo ra một chuỗi trung gian (mà sẽ xảy ra nếu bạn sử dụng một hàm chuỗi lười biếng như lọc)

Nếu bạn đã có một chuỗi nhận ra, thì sau đây cũng là một lựa chọn tốt, vì nó sẽ được hưởng lợi từ số học nguyên thủy trong vòng lặp:

(defn count-truthy [coll] 
    (loop [s (seq coll) cnt 0] 
    (if s 
     (recur (next s) (if (first s) (inc cnt) cnt)) 
     cnt))) 
Các vấn đề liên quan