2012-01-11 16 views
12

मैं का पालन करते हुए Clojure और हैरान सीखने किया गया है:परेशान: लूप के लिए क्लोजर: जबकि -> अप्रत्याशित व्यवहार?

user=> (for [a (range 1 4) b (range 1 4)] [a b]) 
([1 1] [1 2] [1 3] [2 1] [2 2] [2 3] [3 1] [3 2] [3 3]); _no surprise here_ 

के :while (not= a b) जोड़ते हैं, मैं एक खाली सूची देखने के लिए के रूप में पाश अगर हालत झूठी है बंद कर देना चाहिए उम्मीद है। इस मामले में यह पहला आइटम है जहां a = b = 1 है। चलो देखते हैं:

user=> (for [a (range 1 4) b (range 1 4) :while (not= a b) ] [a b]) 

([2 1] [3 1] [3 2]) ; _surprise!_ 

:while:when को (= a b) जोड़े

को फ़िल्टर करने के बदलने
user=> (for [a (range 1 4) b (range 1 4) :when (not= a b) ] [a b]) 
([1 2] [1 3] [2 1] [2 3] [3 1] [3 2]); _expected_ 

किसी को समझा सकते हैं क्यों (for [ ... :while ..] ...) बर्ताव करता है इस तरह?

मैं ओएस एक्स

पर Clojure 1.3 उपयोग कर रहा हूँ धन्यवाद और स्वरूपण की कमी के लिए माफी माँगता हूँ। यह StackOverflow पर मेरी कुंवारी पोस्ट है।

उत्तर

9

चलिए प्रत्येक पुनरावृत्ति को देखते हैं।

a = 1 
    b = 1 -> a == b, break because of while 

a = 2 
    b = 1 -> a != b, print [2 1] 
    b = 2 -> a == b, break because of while 

a = 3 
    b = 1 -> a != b, print [3 1] 
    b = 2 -> a != b, print [3 2] 
    b = 3 -> a == b, break because of while 
+0

धन्यवाद, निकिता। तो अगर: केवल अंदरूनी पाश पर लागू होता है, तो मैं बाहरी लूप पर भी इसे कैसे लागू करूं? मेरी समस्या यह है: (के लिए [से: ए: बी: सी: डी: ई: एफ] से [: ए: बी: सी: डी: ई: एफ]: चलो [पथ (ढूंढने वाला पथ अब)] : पथ के दौरान) पथ); पथ शून्य होने पर लूप बंद होना चाहिए। – jbear

+0

क्षमा करें, मेरा मतलब है (के लिए [से: ए: बी: सी: डी: ई: एफ] से [: ए: बी: सी: डी: ई: एफ]: चलो [पथ (खोजने के लिए पथ) ]: जबकि पथ] पथ) – jbear

+0

@ जेबियर, मुझे नहीं पता :(हो सकता है कि आप बेहतर तरीके से आलसी सीक बनाएं और जब वे शून्य न हों, मुझे यकीन नहीं है कि 'for' आलसी है। –

3

for में :while हालत केवल भीतरी सबसे पाश समाप्त हो जाता है। मैं हर समय for का उपयोग करता हूं, लेकिन :while इतना ही कम है कि मैंने इसे कभी नहीं समझा; महान सवाल के लिए धन्यवाद!

दुख की बात है मुझे लगता है कि सबसे अच्छा तुम कर सकते हो for के चारों ओर एक take-while लपेट, जब से तुम एक "वैश्विक" उत्पादन क्रम पर रोकने के काउंटर इनपुट दृश्यों आप पुनरावृत्ति कर रहे हैं में से एक पर, नहीं रोक-काउंटर चाहते है ऊपर। उदाहरण के लिए:

(->> (for [a (range 1 4) 
      b (range 1 4)] 
     [a b]) 
    (take-while (fn [[a b]] (not= a b)))) 

() 
+1

बस स्पष्ट होने के लिए,': जबकि 'परीक्षण अनुक्रम पर तुरंत लागू होता है, जरूरी नहीं कि आंतरिक-अधिकांश लूप। –

+0

स्पष्टीकरण के लिए धन्यवाद, एलेक्स। भाषा की प्रमुखता देना, मैं थोड़ा निराश महसूस करने में मदद नहीं कर सकता था कि मौलिक बिल्डिंग ब्लॉक में से एक - _list comprehension_ - बल्कि सीमित होना चाहिए। उम्मीद है कि मेरी शिक्षा में प्रगति होती है, मैं बहुत मदद के साथ इसे करने के अधिक/बेहतर तरीके खोजूंगा हर किसी से। – jbear

+0

@ जेबियर यह वास्तव में इस तरह से कम इस तरह से सीमित है उल दूसरे तरीके से हो। इस तरह, यदि आप "वैश्विक" व्यवहार चाहते हैं, तो आप 'ले-टाइम' में आसानी से 'के लिए' अभिव्यक्ति को लपेट सकते हैं। लेकिन अगर "ग्लोबल" व्यवहार 'के लिए' किया गया था, तो आप वर्तमान "मध्यवर्ती" व्यवहार को कैसे वापस ले लेंगे? आपको पूरी तरह से 'के लिए' छोड़ना होगा और नक्शा, मैपकैट, फ़िल्टर, ले-टाइम के चूहे का घोंसला बनाना होगा। – amalloy

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