2013-02-23 25 views
7

Tôi muốn lọc một bộ, một cái gì đó như:Lọc một tập trong Clojure clojure.set/chọn vs clojure.core/lọc

(filter-set even? #{1 2 3 4 5}) 
; => #{2 4} 

Nếu tôi sử dụng clojure.core/filter tôi nhận được một seq mà không phải là một thiết lập:

(filter even? #{1 2 3 4 5}) 
; => (2 4) 

Vì vậy, tốt nhất tôi đến với là:

(set (filter even? #{1 2 3 4 5})) 

Nhưng tôi không thích nó, không giống tối ưu để đi từ các thiết lập để li st trở lại để thiết lập. Điều gì sẽ là cách Clojurian cho điều này?

CẬP NHẬT

tôi đã làm như sau để so sánh cách tiếp cận @ A.Webb và @Beyamor. Điều thú vị là cả hai đều có hiệu suất gần như giống nhau, nhưng clojure.set/select thì tốt hơn một chút.

(defn set-bench [] 
    (let [big-set (set (take 1000000 (iterate (fn [x] (int (rand 1000000000))) 1)))] 
    (time (set (filter even? big-set))) ; "Elapsed time: 422.989 msecs" 
    (time (clojure.set/select even? big-set))) ; "Elapsed time: 345.287 msecs" 
    nil) ; don't break my REPL ! 
+2

Cần lưu ý rằng hiệu suất của 'clojure.set/select' phải giống như' (set (filter ...)) '. Hãy thử thời gian nó cho một tập hợp lớn. Hãy nhớ rằng (1) 'filter' không thực sự tạo ra toàn bộ danh sách vì nó lười và (2) Clojure là tất cả về cấu trúc dữ liệu không thay đổi, vì vậy bạn phải bắt đầu buông bỏ sự ác cảm tự nhiên để tạo cấu trúc mới. –

+0

@ A.Webb thú vị, xem cập nhật của tôi trong câu hỏi. – Blacksad

Trả lời

9

clojure.set là một API tiện dụng cho các hoạt động thiết lập chung.

Trong trường hợp này, clojure.set/select là bộ lọc được đặt cụ thể. Nó hoạt động bằng cách tách các phần tử không đáp ứng được vị từ từ tập hợp đã cho.

(require 'clojure.set) 

(clojure.set/select even? #{1 2 3 4 5}) 
; => #{2 4} 
+0

Tôi không biết làm thế nào tôi bị mất trong tài liệu clojure.set. Cảm ơn ! – Blacksad

Các vấn đề liên quan