2012-06-29 11 views
14

Olası Çoğalt: Bazı HTML Ayrıştırma HTMLAgilityPack ve C# kullanıyorum
Getting odd/even part of a sequence with LINQ
How can I get every nth item from a List<T>?IEnumerable <T>'da çift/tek öğeleri seçin?

.

<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> 

Temel olarak, her biri kendi nesnesinde IEnumerable'ın içinde bu elemanlara sahibim.

Her N/2 öğesinin koleksiyona alınması için zarif bir yol var mı? Anlamı, her div üzerinde .ruler sınıfı ile atlayın?

Ortaya çıkan kümede yinelemeliyim, bu nedenle ya bulduğum her nesneyi yeni bir IEnumerable'a kopyalayın ya da foreach işlevinde satır içi olarak kullanın.

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

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

seçenekleri iyi olurdu ve nasıl bu zarif elde edebilirsiniz: Örneğin

? Bu çözüm hakkında sevmiyorum

+0

Mümkün kopyalar: [LINQ ile bir dizinin tek/çift kısmının alınması] (http://stackoverflow.com/questions/267033/getting-odd-even-part-of-a-sequence-with-linq), [ Her bir maddeyi bir Listeden nasıl alabilirim ?] (Http://stackoverflow.com/questions/682615/how-can-i-get-every-nth-item-from-a-listt) – mellamokb

cevap

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

tek şey oran ve eşitler hem gerekirse iki kez yineleme diziyi gerektirmesidir. Herhangi bir nedenle bu kaçınmak gerekir, daha çok çalışmak gerekecek:

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

Sonra oran Keyfalse olduğunu groups olan elemanlardır ve eşitler groupsKey olan elemanlardır true geçerli:

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

+1 I İkinci yaklaşımın arkasındaki fikir gibi. Ancak, bu basit sürümünden daha hızlı ise gerçekten merak ediyorum. Orijinal koleksiyonu iki kez saymak zorunda değilsiniz, ancak isimsiz olarak yazılan nesnelerin oluşturulması, gruplandırılması ve sözlüğün oluşturulmasıyla, bunun gerçekten ne kadar ödeyeceğini bilmiyorum ... Ne düşünüyorsun? –

+0

@PhilipDaubmeier: Bence buna bağlı. Eğer sonuçtan sadece 'Take (1000)' iseniz, ilk yaklaşım daha hızlı olabilir, en azından önemli değil. Eğer hepsini (örneğin, Count() ',' foreach' veya 'ToList()' kullanarak) kullanırsanız, 'Dictionary' (Yaklaşım) yaklaşımı önemli ölçüde daha hızlı olabilir. –

+0

Bu arada, Sözlük yaklaşımı bir 'OutOfMemoryException ', 36GB ramlı bir PC üzerinde bir hugelist ile oysa çift-'Where' her zaman çalıştı ve sadece bir altkümeyi (fe' Take (1000) 'olarak alırsanız gerçekten hızlıydı. yukarıda bahsedilen). –

3
sadece bu amaç için kendi uzantısı yöntemi tanımlayabiliriz

:

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; 
     } 
    } 
} 
İlgili konular