2013-09-06 8 views
6

क्या Clojure में मुहावरेदार तरीका है take-while-and-n-more नीचे लागू करने के लिए:Clojure ले, जबकि और n अधिक आइटम

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

मेरे कोशिश है:

(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)))))) 

उत्तर

9

मैं split-with, जो दोनों ले, जबकि के परिणाम प्राप्त करने के बराबर है का उपयोग करें और ड्रॉप-, जबकि एक ही पैरामीटर के लिए होगा:

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

निम्नलिखित कोड Clojures take-while का एक संशोधित संस्करण है । जहां क्लोजर take-whilenil को डिफ़ॉल्ट केस के रूप में लौटाता है (जब पूर्वानुमान मेल नहीं खाता है), यह भविष्यवाणी विफल होने के बाद अतिरिक्त आइटम लेने के लिए take को आमंत्रित करता है।

ध्यान दें कि split-with का उपयोग कर संस्करणों के विपरीत, यह संस्करण केवल एक बार अनुक्रम को पार करता है।

(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 एक आलसी अनुक्रम देता है – soulcheck

+0

आप सही हैं। मैंने अपना जवाब संपादित किया। फिर भी, विभाजन के साथ क्रमशः अनुक्रम के मिलान-मिलान भाग को पार करने में परिणाम मिलेगा। –

3

फिर भी एक और तरीका है:

(defn take-while-and-n-more [pred n coll] 
    (let [[a b] (split-with pred coll)] 
    (concat a (take n b)))) 
संबंधित मुद्दे