2009-06-28 16 views
11

मैं clojure मैं यह पता लगाने निम्नलिखित कलन विधि को लागू करने के लिए कैसे करने के लिए कोशिश कर रहा हूँ की कोशिश कर रहा,Clojure जबकि लूप

मैं एक इनपुट धारा मैं जब तक यह एक सीमांकक चरित्र नहीं है पढ़ने जारी रखना चाहते से पढ़ रहा हूँ।

मैं जावा में थोड़ी देर के साथ ऐसा कर सकता हूं लेकिन मुझे लगता है कि क्लोजर में इसे कैसे करना है?

 
while 
    read 
    readChar != delimiter 

    do some processing.... 
end while 

उत्तर

10

मैं Clojure पता नहीं है, लेकिन यह है कि, योजना की तरह, यह समर्थन करता है, "छोरों दो" दिखता है:

(loop [char (readChar)] 
    (if (= char delimiter) 
     '() 
     (do (some-processing) 
      (recur (readChar))))) 

आशा इस आपके प्रारंभ करने के लिए पर्याप्त है। इस प्रश्न का उत्तर देने के लिए मैंने http://clojure.org/special_forms#toc9 पर संदर्भित किया।

नोट: मुझे पता है कि क्लोजर साइड इफेक्ट्स को हतोत्साहित करता है, इसलिए संभवतः आप '() के बजाय कुछ उपयोगी लौटना चाहते हैं।

+0

साइड इफेक्ट के बारे में सही। हो सकता है कि लूप में एक संचयक को यह दिखाने के लिए कि परिणाम कैसे कार्यान्वित किया गया है? –

2

मैं line-seq की भावना में इसके साथ आया था। यह पूरी तरह से आलसी है और loop की तुलना में क्लोजर की कार्यात्मक प्रकृति का अधिक प्रदर्शन करता है।

(defn delim-seq 
    ([#^java.io.Reader rdr #^Character delim] 
    (delim-seq rdr delim (StringBuilder.))) 
    ([#^java.io.Reader rdr #^Character delim #^StringBuilder buf] 
    (lazy-seq 
     (let [ch (.read rdr)] 
     (when-not (= ch -1) 
      (if (= (char ch) delim) 
      (cons (str buf) (delim-seq rdr delim)) 
      (delim-seq rdr delim (doto buf (.append (char ch)))))))))) 

Full paste

+0

एक छोटा रास्ता होना चाहिए 'टा यह करो। – Kzqai

1

एक समय-लूप में आमतौर पर परिवर्तनीय चर शामिल होते हैं, यानी एक चर एक निश्चित स्थिति को पूरा करने तक प्रतीक्षा करते हैं; क्लोजर में आप आम तौर पर पूंछ-रिकर्सन (जो संकलक एक समय-लूप में अनुवाद करता है) का उपयोग करता है

निम्नलिखित समाधान नहीं है, लेकिन कुछ मामलों में फॉर-लूप की यह भिन्नता मदद की जा सकती है:

(for [a (range 100) 
     b (range 100) 
     :while (< (* a b) 1000)] 
    [a b] 
) 

यह(< (* a b) 1000) जब तक एक के सभी जोड़े और ख की एक सूची का निर्माण करेगा। जैसे ही स्थिति पूरी हो जाती है, वैसे ही यह बंद हो जाएगा। यदि आप प्रतिस्थापित करते हैं: जबकि: जब, वे सभी जो स्थिति को पूरा करते हैं, उनमें से कोई भी ऐसा नहीं मिलने के बाद भी मिल सकता है।

5

Clojure 1.3.0 पर काम करते हुए, और क्या इसके लायक है, तो आप जबकि Clojure में छोरों अब

(while truth-expression 
    (call-some-function)) 
+0

यह सत्य-अभिव्यक्ति को अंततः गलत होने के लिए कुछ दुष्प्रभावों पर निर्भर करता है। – tenpn

3

पाश दृष्टिकोण के लिए कुछ समान करके clojure लेकिन पाश/पुनरावृत्ति होना में अच्छा काम कर रहे हैं लिख सकते हैं माना जाता है कि निम्न स्तर के संचालन और उच्च आदेश कार्यों को आम तौर पर पसंद किया जाता है।

आम तौर पर समस्या इस तरह की टोकन के एक अनुक्रम बनाने के द्वारा हल किया जा सकता है (अपने उदाहरण में अक्षर) और पर या clojure के अनुक्रम कार्य (doseq, dorun, ले, जबकि, आदि)

के अधिक आवेदन करने उदाहरण के बाद सिस्टम जैसे यूनिक्स पर/etc/passwd से पहला उपयोगकर्ता नाम पढ़ता है।

(require '[clojure.java [io :as io]]) 

(defn char-seq 
    "create a lazy sequence of characters from an input stream" 
    [i-stream] 
    (map char 
    (take-while 
    (partial not= -1) 
    (repeatedly #(.read i-stream))))) 

;; process the sequence one token at a time 
;; with-open will automatically close the stream for us 

(with-open [is (io/input-stream "/etc/passwd")] 
    (doseq [c (take-while (partial not= \:) (char-seq is))] 
    ;; your processing is done here 
    (prn c))) 
0

मैं इस संस्करण के साथ बाहर आया था:

(defn read-until 
    [^java.io.Reader rdr ^String delim] 
    (let [^java.lang.StringBuilder salida (StringBuilder.) ] 
    (while 
     (not (.endsWith (.toString salida) delim)) 
     (.append salida (str (char (.read rdr)))) 
    ) 
    (.toString salida) 
) 
) 

यह एक स्ट्रिंग, नहीं परिसीमक के रूप में एक भी चार के लिए लग रहा है!

धन्यवाद!

संबंधित मुद्दे