2012-06-29 7 views
14

संभव डुप्लिकेट:
Getting odd/even part of a sequence with LINQ
How can I get every nth item from a List<T>?IENumerable <T> में भी/विषम तत्वों का चयन करें?

मैं उपयोग कर रहा हूँ HtmlAgilityPack और सी # कुछ HTML पार्स करने के लिए।

<div id="post-8266"> 
<div class="ruler"> </div> 
<div id="post-8266"> 
<div class="ruler"> </div> 
<div id="post-8266"> 
<div class="ruler"> </div> 
<div id="post-8266"> 
<div class="ruler"> </div> 

असल में, मेरे पास ये तत्व हैं, प्रत्येक अपनी वस्तु में, एक आईनेमेरेबल के अंदर।

संग्रह में प्रत्येक एन/2 तत्व प्राप्त करने का एक शानदार तरीका है। मतलब, कक्षा .ruler के साथ प्रत्येक div पर छोड़ दें?

मुझे परिणामी सेट के माध्यम से पुन: प्रयास करना होगा, इसलिए या तो मैं प्रत्येक पाए गए ऑब्जेक्ट को एक नए आईनेमरेबल में कॉपी करता हूं या केवल इसे फ़ोरैच फ़ंक्शन में इनलाइन का उपयोग करता हूं।

//Copying resulting set to new IEnumerable<T>: 
var odds = elements.SelectOdds(); 

//Using it inline for my usage: 
foreach (var x in elements.SelectOdds()) 
{ 
} 

कौन सा विकल्प सबसे अच्छा होगा, और कैसे मैं इस सुंदर ढंग से प्राप्त कर सकते हैं:

उदाहरण के लिए

?

+0

संभावित डुप्लीकेट: [LINQ के साथ अनुक्रम का अजीब/यहां तक ​​कि भाग प्राप्त करना] (http://stackoverflow.com/questions/267033/getting-odd-even-part-of-a-sequence-with-linq), [ मैं प्रत्येक nth आइटम को सूची से कैसे प्राप्त कर सकता हूं?] (Http://stackoverflow.com/questions/682615/how-can-i-get-every-nth-item-from-a-listt) – mellamokb

उत्तर

27
var odds = sequence.Where((item, index) => index % 2 != 0); 
var evens = sequence.Where((item, index) => index % 2 == 0); 

केवल एक चीज है कि मैं इस समाधान के बारे में पसंद नहीं है कि यह बार-बार दोहराना अनुक्रम की आवश्यकता होती दो बार अगर तुम दोनों बाधाओं और evens की जरूरत है। किसी कारण से आप इस से बचना चाहिए, तो आप ज्यादा मेहनत करनी होगी: फिर

var groups = sequence.Select((item, index) => new { Item = item, Index = index }) 
        .GroupBy(x => x.Index % 2 == 0) 
        .ToDictionary(g => g.Key, g => g); 

, बाधाओं groups जहां Keyfalse है की उन तत्वों रहे हैं, और evens groups जहां Key के उन लोगों के तत्व हैं true है:

var odds = groups[false]; 
var evens = groups[true]; 
+1

+1 I दूसरे दृष्टिकोण के पीछे विचार की तरह। हालांकि, अगर मैं सरल संस्करण से तेज़ हूं तो मैं वास्तव में उत्सुक हूं। आपको मूल संग्रह को दो बार गणना करने की ज़रूरत नहीं है, लेकिन गुमनाम रूप से टाइप की गई वस्तुओं के निर्माण के साथ, समूहकरण और शब्दकोश का निर्माण, मुझे नहीं पता कि यह वास्तव में भुगतान करता है ... आपको क्या लगता है? –

+0

@ फिलिपडाउबमेयर: मुझे लगता है कि यह निर्भर करता है। यदि आप नतीजे से केवल 'ले लो (1000) 'पहला दृष्टिकोण भी तेज हो सकते हैं, कम से कम इससे कोई फर्क नहीं पड़ता। यदि आप सभी को ले लेंगे (उदाहरण के लिए 'गणना() ',' foreach' या 'ToList()') का उपयोग करके' शब्दकोश 'दृष्टिकोण काफी तेज़ हो सकता है। –

+0

वैसे, डिक्शनरी दृष्टिकोण एक 'आउटऑफमेमरीएक्सप्शन' का कारण बनता है जिसमें एक पीसी पर 36 जीबी रैम वाला एक ह्यूजलिस्ट होता है जबकि डबल-'वेयर' हमेशा काम करता है और वास्तव में तेज़ होता है यदि आप केवल एक सबसेट लेते हैं (fe 'Take (1000)' उपर्युक्त)। –

3

तुम सिर्फ इस उद्देश्य के लिए अपने स्वयं के एक्सटेंशन विधि निर्धारित कर सकते हैं:

public static class LinqExtensions 
{ 
    public static IEnumerable<T> SelectOdds<T>(this IEnumerable<T> enumerable) 
    { 
     bool odd = false; 

     foreach (var item in enumerable) 
     { 
      if (odd) 
       yield return item; 

      odd = !odd; 
     } 
    } 
} 
संबंधित मुद्दे