2012-09-20 17 views

Odpowiedz

19

Jeśli chcesz zachować wartości truthy wystarczy użyć funkcji identity:

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

Ta odpowiedź jest fajna! – murtaza52

3

Wystarczy usunąć wartości, które nie chcą się liczyć.

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

drobny błąd: (count (remove nil? [1 2 3 zero zero false])) => 4 –

+0

możesz to naprawić, zamieniając 'nil?' Na '# (jeśli% false true)' –

+2

# (jeśli% false true) jest absolutnie równoważne funkcji nie . (count (remove not [1 2 3 zero zero false])) zwraca poprawny wynik. – animal

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

Chociaż muszę przyznać, że podoba rozwiązanie Dani jest lepiej.

2

genral wzór jest filtrowanie sekwencję i policzyć wyniki

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

#(if % %) jest tylko krótki test truthyness które zwraca element tylko wtedy, gdy jest truthy lub coś falsy (zero) w przeciwnym wypadku

+0

Jakie to ma zalety, jeśli w ogóle, przez '(count (filtr (podejście identyczne? – noahlz

+0

to po prostu inny sposób wyrażania pojęcia" jeśli ten przedmiot jest zgodny z prawdą "osobiście uważam, że jest to bardziej zrozumiałe, ale to tylko moje opinia –

6

polecam zrobić to ze zmniejszenia się następująco:

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

powody korzystania zmniejszyć w ten sposób:

  • Jest prawdopodobne, aby być bardziej wydajne i będą korzystać z nowej funkcjonalności Clojure za reduktorów, które umożliwia fakt, zmniejsza w wielu kolekcjach
  • unika tworzenia sekwencję pośrednią (co by było, gdyby użyto leniwe funkcję sekwencji takiego filtra)

Jeśli masz już zrealizowane sekwencję, wówczas następujące jest również dobrym rozwiązaniem, ponieważ będzie ona korzystać z prymitywnego arytmetyki w pętli:

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