2013-09-06 19 views
6

gì là cách thành ngữ trong Clojure để thực hiện take-while-and-n-more dưới đây:Clojure mất-thời gian và n đối tượng nào

=> (take-while-and-n-more #(<= % 3) 1 (range 10)) 
(0 1 2 3 4) 

thử của tôi là:

(defn take-while-and-n-more [pred n coll] 
    (let 
     [take-while-result (take-while pred coll) 
     n0 (count take-while-result)] 
    (concat 
    take-while-result 
    (into [] (take n (drop n0 coll)))))) 

Trả lời

9

Tôi sẽ sử dụng split-with, đó là tương đương với việc nhận được kết quả của cả hai mang về thời gian và thả trong khi đối với các thông số tương tự:

(defn take-while-and-n-more [pred n coll] 
    (let [[head tail] (split-with pred coll)] 
     (concat head (take n tail)))) 
1

Đoạn mã dưới đây là một phiên bản sửa đổi của Clojures take-while . Trường hợp Clojures take-while trả về nil làm trường hợp mặc định (khi vị từ không khớp), điều này gọi take để nhận các mục bổ sung sau khi vị từ không thành công.

Lưu ý rằng không giống như các phiên bản sử dụng split-with, phiên bản này chỉ di chuyển một lần.

(defn take-while-and-n-more 
    [pred n coll] 
    (lazy-seq 
    (when-let [s (seq coll)] 
    (if (pred (first s)) 
     (cons (first s) (take-while-and-n-more pred n (rest s))) 
     (take n s))))) 
+0

concat trả về một chuỗi lười biếng – soulcheck

+0

Bạn nói đúng. Tôi đã chỉnh sửa câu trả lời của mình. Tuy nhiên, việc chia nhỏ sẽ dẫn đến việc vượt qua phần khớp vị ngữ của chuỗi hai lần. –

3

Tuy nhiên, một cách khác:

(defn take-while-and-n-more [pred n coll] 
    (let [[a b] (split-with pred coll)] 
    (concat a (take n b)))) 
Các vấn đề liên quan