2011-10-01 14 views
12

से आइटम का उपभोग करें मैं Iterator पर विधि take के व्यवहार के बारे में उलझन में हूं। ऐसा लगता है कि यह वस्तुओं का उपभोग नहीं करता है।स्कैला Iterator

scala> Iterator(1,2,3) 
res0: Iterator[Int] = non-empty iterator 

scala> res0 take 2 toArray 
res1: Array[Int] = Array(1, 2) 

scala> res0.next 
res2: Int = 1 

जाहिर कदम 2 दो आइटम की खपत है, लेकिन चरण 3 में Iterator पहला आइटम पर अभी भी है: यहाँ एक उदाहरण है। कार्यान्वयन को देखते हुए, मैं किसी भी प्रकार की प्रतिलिपि या बफरिंग नहीं देख सकता, केवल एक नया Iterator अंतर्निहित एक प्रतिनिधि प्रतिनिधि। यह कैसे संभव हो सकता है? मैं वास्तव में n आइटमों का उपभोग करने के लिए कैसे प्रबंधित कर सकता हूं?

उत्तर

10

प्रश्न में पुनरावर्तक IndexedSeqLike#Elements (source) में परिभाषित किया गया है। विभिन्न पुनरावर्तक कार्यान्वयन में take के असंगत व्यवहार के बारे में ticket was recently filed

वास्तव में एन आइटम का उपभोग करने के लिए, Iterator#next एन बार कॉल करें।

आप Stream का उपयोग करने पर विचार करना चाहेंगे, जो एक आलसी है (जैसे Iterator), लेकिन यह भी अपरिवर्तनीय है (Iterator के विपरीत)।

scala> val s = Stream(1, 2, 3) 
s: scala.collection.immutable.Stream[Int] = Stream(1, ?) 

scala> s.take(2).toList 
res43: List[Int] = List(1, 2) 

scala> s.take(2).toList 
res44: List[Int] = List(1, 2) 

scala> s.drop(2).toList 
res45: List[Int] = List(3) 

scala> {val (s1, s2) = s.splitAt(2); (s1.toList, s2.toList)} 
res46: (List[Int], List[Int]) = (List(1, 2),List(3)) 
+0

धन्यवाद संक्षिप्त नाम, मैं बिंदु देखता हूं। मुझे 'स्ट्रीम' को छोड़ने के लिए "वर्तमान आइटम सूचक" की तरह कुछ की कमी थी (वैसे, शायद जावा प्रभाव के कारण, किसी चीज़ को किसी तथाकथित चीज़ में उम्मीद हो सकती है)। अब मैं देखता हूं कि मुझे 'ड्रॉप पॉइंट' के अनुक्रम के साथ "वर्तमान सूचक" मिल सकता है और 'हेड' को देख सकता है। मैं दुबारा कोशिश करूँगा। – jglatre

1

आप आइटम, drop उन्हें उपभोग करना चाहते हैं। ध्यान दें कि Iterator पर बुलाए जाने वाले अधिकांश तरीकों से Iterator आगे उपयोग के लिए बेकार हो जाएगा - इस अर्थ में बेकार है कि व्यवहार अपरिभाषित है और परिवर्तन के अधीन है।

+0

'ड्रॉप' वास्तव में 'ले' के समान असंगतता के अधीन है। '{वैल i = Iterator (1, 2, 3); i.drop (1); i.next} 'रिटर्न' 1', '2' नहीं। – retronym

+1

@retronym एक बार जब आप 'i' पर 'ड्रॉप' कहलाते हैं, तो' i' का विश्वसनीय रूप से उपयोग नहीं किया जा सकता है। इसके बजाए, आपको 'ड्रॉप' वापस लौटने का उपयोग करना होगा। –

+0

अच्छा बिंदु। '{वैल i = Iterator (1, 2, 3); i.drop (1) .next} 'देता है 2. सब कुछ लेकिन 'अगला()' और 'हैनक्स्ट()' (संभावित रूप से) मूल पुनरावर्तक को अमान्य करता है; हालांकि वे विधियां * नया *, वैध, इटरेटर वापस कर सकती हैं। मैं इसे स्पष्ट करने के लिए आपके दस्तावेज़ योगदान के लिए तत्पर हूं। – retronym

2

धन्यवाद दोस्तों।

यह एक Iterator से आइटम के गुच्छों उपभोग करने के लिए मेरे समाधान है:

implicit def consumable(i: Iterator[_]) = new { 
    def next(n: Int) = { 
     (for (_ <- 1 to n) yield i.next()).iterator 
    } 
    def skip(n: Int) { 
     (1 to n).foreach(_ => i.next()) 
    } 
    } 

कोई टिप्पणी का स्वागत किया जाएगा।

+0

रिटर्न प्रकार के साथ संगत होने के लिए परिभाषा होना चाहिए: निहित डीई उपभोग्य [टी] (i: Iterator [टी]) अन्यथा यह इटरेटर [किसी भी] – Miquel