2013-06-25 45 views
5

Ben listelerin bir dizi var gitmek Verilen bir özelliğin (bar) son listede yer aldığı bir değere sahip olduğu tüm foo 'seslerinin referanslarını yakalamak. Böyle yapıyorum: Sorgu birden çok liste

func<foo, bool> deadParrot = x => Brian.Contains(x.bar); 

IEnumerable<foo> okLumberjacks = spamSpamAndSpam.Where(deadParrot); 
okLumberjacks = okLumberjacks.Concat(
    spamSpamSpamSpamSausageEggsAndSpam.Where(deadParrot)); 

// And so on, concatenating the results of Where() from every list of <foo>. 

böyle, ben tek seferde hepsini bir yöntemi çağırmak, böylece tek bir IEnumerable<foo> filtreleme fonksiyonu karşıladığında her foo gerekir:

ni = ni.Concat(someList.Where(filter)); 

I:

foreach (foo incontinentRunner in okLumberjacks) 
{ 
    incontinentRunner.SillyWalk(); 
} 

benim soru gibi bir şey başvurmak zorunda kalmadan tek bir koleksiyonda her foo toplamak için bir yol ... var mı olduğunu Yani Linq ile böyle bir şey yapmak için daha zarif bir yol var mı?

okLumberjacks = spamSpamAndSpam. 
    And(spamSpamSpamSausageEggsAndSpam). 
    And(spamSpamSpamSausageEggsBaconAndSpam) /* etc */ .Where(deadParrot); 

Veya daha iyi: onlar daha sonra başka bir işlem için olduğu gibi onları gerektiğinden foo orijinal listelerini değiştirmek istemiyorum

okLumberjacks = spanishInquisition.Where(deadParrot); 
// Where the type of spanishInquisition is List<List<foo>>. 

Ben böyle bir şey arıyorum kodda.

+0

Kodunuzdaki tüm OfType çağrıları hiçbir şey yapmaz; zaten belirtilen türden bir 'IEnumerable' var, bu yüzden sadece bir noop. – Servy

+0

@Servy iyi bir nokta. Ama Sharepoint kullanıyorum ... Koleksiyon sınıflarının hiçbiri IEnumerable 'u uygulamamaktadır, ne de' Where' uzantısı yöntemini sergilememektedir, ancak bunların hepsi OfType'ı açığa çıkarmaktadır ve ben Linq için yeniyim. OfType'ı kaldırmak için soruyu düzenliyorum. Daha fazla Monty Python referansları için – Renan

+4

+1 bir SO soru mümkün olabileceğini düşündüm. – Kevin

cevap

5

listelerin bir listesini oluşturun ve sonra sadece düzleştirmek:

List<List<foo>> lists = new List<List<foo>>() 
{ 
    spamSpamAndSpam, 
    spamSpamSpamSausageEggsAndSpam, 
    //etc. 
}; 

IEnumerable<foo> items = lists.SelectMany(item => item); 
//do stuff with items. 
+0

Güzel.Bu benim aradığım şeydi :) – Renan

2

aklıma gelen en iyi olurdu gibi bir şey:

var everything = spam1.Concat(spam2).Concat(spam3); 
var itemsIWant = everything.Where(x => Brian.Contains(x)); 
+0

“Concat” işlemlerini yerleştirmek yerine onları daha kolay sözdizimi için zincirleyebilirsiniz: 'first.Concat (second) .Concat (third) .Concat (dördüncü);' – Servy

+0

@Servy: Thanks ... garip bir şey biliyordu. –

+0

Bunu neden denemedim bilmiyorum ... Orijinal listelerini değiştireceğini düşündüm, ama test ettim ve görmedim. +1. – Renan

1

mu Birliği() sorununuzu çözmek?

 List<foo> spamSpamAndSpam; 
     List<foo> spamSpamSpamSausageEggsAndSpam; 
     List<foo> spamSpamSpamSausageEggsBaconAndSpam; 
     List<foo> spamSpamSpamSpamSpamWithoutSpam; 
     List<foo> spamSpamSpamSpamSpamSpamSpamSpamSpamLovelySpamWonderfulSpam; 

     var x = spamSpamAndSpam 
      .Union(spamSpamSpamSausageEggsAndSpam) 
      .Union(spamSpamSpamSausageEggsBaconAndSpam) 
      .Union(spamSpamSpamSausageEggsBaconAndSpam) 
      .Union(spamSpamSpamSpamSpamWithoutSpam) 
      .Union(spamSpamSpamSpamSpamSpamSpamSpamSpamLovelySpamWonderfulSpam) 
      .Where(x => .....); 

NOT: Düzgün kaydedildi olarak, Union dönüş kümesinden çiftleri dışlar. Bu, çoğaltma dahil giriş dizilerindeki tüm öğeleri döndüren Concat yöntemine farklı bir davranıştır. Yinelenen hariç tutma bir gereklilik olmadığı için, Concat muhtemelen daha iyi

+0

Ayrıca yapar. Teşekkürler, bu soruyla çok şey öğreniyorum. Eve geldiğimde her uzatma yöntemi için belgeleri tekrar okuyacağım. – Renan

+0

Birlik, açık bir hedef olarak belirtmediği yinelemeleri kaldıracaktır. Ve eğer çift varsa, onlar için zaman/çaba/bellek kontrolü boşa harcıyorsunuz demektir. "Concat" neredeyse "Union" ile aynıdır, ancak çift kontrol olmadan, ve burada daha uygun operatör olarak görünüyor. – Servy

+0

@Servy bilmek güzel. Ancak çoğaltma eşitlik operatörü ile test edilir, değil mi? Yani aynı özellik değerlerine sahip iki nesne hala farklı olarak değerlendirilir, değil mi? – Renan

İlgili konular