क्या यह संभव है कि पहली बार उपयोग किए जा रहे फ़ार्म के अलावा किसी अन्य तत्व से पुनरावृत्ति शुरू हो?


86

मैं अपने कस्टम संग्रह (एक पेड़) के लिए IEnumerable को लागू करने के बारे में सोच रहा हूं ताकि मैं अपने पेड़ को पार करने के लिए foreach का उपयोग कर सकूं। हालाँकि, जहाँ तक मुझे पता है कि हमेशा संग्रह के पहले तत्व से शुरू होता है। मैं यह चुनना चाहूंगा कि कौन से तत्व से शुरू होता है। क्या यह संभव है कि किसी भी तरह से उस तत्व को बदल दिया जाए जिसमें से फ़ॉर्च शुरू होता है?


1
मैं कम से कम विस्मय के सिद्धांत का पालन करूंगा: en.wikipedia.org/wiki/Principle_of_least_astonishment
ChaosPandion

यदि आप पहले तत्व से शुरू नहीं करते हैं, तो आप इटरेटर के व्यवहार को कैसे परिभाषित करते हैं? अनुक्रम के अंत तक पहुंचने पर क्या होता है? क्या यह फिर पहले तत्व पर वापस जाता है और शेष तत्वों पर पुनरावृति करता है?
दान जे

@ ChaosPandion की टिप्पणी वह है जहां मैं उन सवालों के साथ जा रहा था। :)
डैन जे

जवाबों:


162

हाँ। निम्न कार्य करें:

Collection<string> myCollection = new Collection<string>;

foreach (string curString in myCollection.Skip(3))
    //Dostuff

Skipएक IEnumerable फ़ंक्शन है जो कि आपके द्वारा निर्दिष्ट वर्तमान सूचकांक पर शुरू होने वाले कई को छोड़ देता है। दूसरी ओर, यदि आप केवल पहले तीन का उपयोग करना चाहते हैं, तो आप उपयोग करेंगे .Take:

foreach (string curString in myCollection.Take(3))

इन्हें एक साथ जोड़ा भी जा सकता है, इसलिए यदि आप केवल 4-6 आइटम चाहते हैं जो आप कर सकते हैं:

foreach (string curString in myCollection.Skip(3).Take(3))

अच्छा निर्णय। डब्ल्यूटीबी ऑटो-कम्प्लीट (गाह स्टैकओवरफ़्लो में इसका असली नाम याद नहीं कर सकते हैं;)
मूरकोडप्लाज़

क्या यह वास्तव में छोड़ता है या यह सिर्फ एक प्रति बनाता है? IE इन दो अलग होगा: foreach(List<string> row in rows.skip(1)){ row[0] = "newInfo"; } बनाम for(int i=1; i<rows.Count;i++){ List<string> row = rows[i]; row[0] = "newStuff"; }
TigerBear

25

Skipतत्वों की दी गई संख्या को छोड़ने के लिए, इसके लिए LINQ में विधि का उपयोग करना सबसे आसान है :

foreach (var value in sequence.Skip(1)) // Skips just one value
{
    ...
}

स्पष्ट रूप से तत्वों की एक अलग संख्या को छोड़ने के लिए किसी भी अन्य मूल्य के लिए सिर्फ 1 बदलें ...

इसी तरह आप उन Takeतत्वों की संख्या को सीमित करने के लिए उपयोग कर सकते हैं जो वापस आ गए हैं।

आप मेरी एडलिनक ब्लॉग श्रृंखला में इन दोनों (और संबंधित SkipWhileऔर TakeWhileविधियों) के बारे में अधिक पढ़ सकते हैं ।


जॉन, क्या यह अपवाद का जोखिम नहीं है यदि "अनुक्रम" अशक्त है?
WEFX

@WEFX: वैसे हमें पता नहीं है कि sequenceवैध रूप से हो सकता है nullया नहीं। संभवतः ओपी खुद को संभाल सकता है - यह वास्तव में सवाल का हिस्सा नहीं है ...
जॉन स्कीट

5

आप कुछ तत्वों को छोड़ने के लिए Enumerable.Skip का उपयोग कर सकते हैं , और यह वहाँ शुरू होता है।

उदाहरण के लिए:

foreach(item in theTree.Skip(9))  // Skips the first 9 items
{
    // Do something

हालाँकि, यदि आप एक पेड़ लिख रहे हैं, तो आप स्वयं उस वृक्ष की वस्तु पर एक सदस्य प्रदान करना चाह सकते हैं IEnumerable<T>जो एक नया लौटाएगा जो वहाँ से नीचे आएगा। यह, संभवतः, लंबे समय में अधिक उपयोगी होगा।


कुछ पसंद है IEnumerable<T> SubTree(rootIndex)? अच्छा निर्णय!
दान जे

उत्तर के लिए धन्यवाद, स्किप करना आशाजनक लगता है, स्किप के बारे में एमएसडीएन जानकारी पढ़ने से मुझे यह निष्कर्ष मिला कि शायद एक विधि StartFrom (यह IEnumerable <MyTree> वृक्ष, MyTreeElement तत्व) लिखना संभव है, जो IEnumerable <MyTree> के लिए एक विस्तार विधि होगी IEnumerable <MyTreeElement> लौटाएगा, जहां से मुझे पुनरावृत्ति शुरू करनी चाहिए। तब शायद मैं इस विधि का उपयोग फॉर्च के रूप में कर सकता हूं (पेड़ में var तत्व ।tartFrom (someElement)))।
नरक

@inferno: हाँ, आप आसानी से कर सकते हैं। हालाँकि, मैं सिर्फ MyTreeElement के लिए एक विधि / संपत्ति जोड़ूंगा जो कि अधिक थी:, IEnumerable<MyTreeElement> Childrenतो आप बस कर सकते हैं: foreach(var item in someElement.Children)- एक्सटेंशन विधियों IMO का उपयोग करने की तुलना में बहुत अधिक स्पष्ट।
रीड कोपसे

-1

Foreachके कार्यान्वयन से परिभाषित तरीके से आपके संग्रह पर पुनरावृति करेगा IEnumerable। इसलिए, यद्यपि आप तत्वों को छोड़ सकते हैं (जैसा कि ऊपर बताया गया है), आप अभी भी उसी क्रम में तत्वों पर तकनीकी रूप से पुनरावृत्ति कर रहे हैं।

सुनिश्चित नहीं है कि आप क्या हासिल करना चाह रहे हैं, लेकिन आपकी कक्षा में कई IEnumerableगुण हो सकते हैं , जिनमें से प्रत्येक तत्वों को एक विशिष्ट क्रम में शामिल किया गया है।


-1

यदि आप एक में पंक्तियों को पढ़ना छोड़ना चाहते हैं DataGridView, तो यह प्रयास करें

foreach (DataGridViewRow row in dataGridView1.Rows.Cast<DataGridViewRow().Skip(3))

यदि आप एक DataGridViewसे दूसरी लंघन पंक्तियों की सामग्री की प्रतिलिपि बनाना चाहते हैं , तो यह प्रयास करें,

foreach (DataGridViewRow row in dataGridView1.Rows.Cast<DataGridViewRow>().Skip(3))
{
    foreach (DataGridViewCell cell in row.Cells)
    {
        string value = cell.Value.ToString();
        dataGridView2.Rows[i].Cells[j].Value = cell.Value.ToString();
        j++;
    }
    i++;
    j = 0;
}

यह सामग्री को एक DataGridViewसे दूसरी लंघन 3 पंक्तियों में कॉपी करता है ।


यह उस प्रश्न का उत्तर नहीं देता है जो पूछा गया था - यह प्रश्न बिल्कुल भी उल्लेख नहीं करता है DataGridView(या यूआई फ्रेमवर्क भी)।
नाइटऑवल 88

@ NightOwl888 इस बात का जवाब दिया गया क्योंकि सवाल कुछ पुनरावृत्तियों को छोड़ने और उसके बाद फ़ॉरच लूप में होने के बारे में था। मेरे उदाहरण में मैंने सिर्फ DataGridView पर आवेदन करने के लिए Skip () का उपयोग किया है।
जुनैद खान मोमिन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.