2011-06-13 18 views
25

Temel olarak, öğenin özelliğinin koleksiyonda olup olmadığının karşılaştırılması dışında, CurrentCollection.Contains(...) benzeri bir şey yapabilmem için nasıl yapabilirim?Koleksiyonun özelliklerinin bir karsılastırılmasıyla koleksiyonu içermiyorsa, koleksiyona öğeler ekleyin?

public class Foo 
{ 
    public Int32 bar; 
} 


ICollection<Foo> CurrentCollection; 
ICollection<Foo> DownloadedItems; 

//LINQ: Add any downloaded items where the bar Foo.bar is not already in the collection? 

cevap

34

Sen elemanları koleksiyonunda yer almayan tüm tespitiyle başlayacak:

var newItems = DownloadedItems.Where(x => !CurrentCollection.Any(y => x.bar == y.bar)); 

Ve sonra sadece onları ekleyin: İlk operasyon boyutu ise kuadratik karmaşıklığı olabileceğini

foreach(var item in newItems) 
{ 
    CurrentCollection.Add(item); 
} 

Not of DownloadedItems, CurrentCollection boyutuna yakındır. Bu sorunlara neden biter olursa (ilk ölçmek!) kullanarak, doğrusal aşağı karmaşıklığı getirmek için bir HashSet kullanabilirsiniz:

// collect all existing values of the property bar 
var existingValues = new HashSet<Foo>(from x in CurrentCollection select x.bar); 
// pick items that have a property bar that doesn't exist yet 
var newItems = DownloadedItems.Where(x => !existingValues.Contains(x.bar)); 
// Add them 
foreach(var item in newItems) 
{ 
    CurrentCollection.Add(item); 
} 
3

Sen Any yöntemini çağırın ve koleksiyonunda nesnenin türü ne olursa olsun özelliğine karşılaştırmak için bir değer iletebilirsiniz

if (!CurrentCollection.Any(f => f.bar == someValue)) 
{ 
    // add item 
} 

daha eksiksiz bir çözüm olabilir:

DownloadedItems.Where(d => !CurrentCollection.Any(c => c.bar == d.bar)).ToList() 
    .ForEach(f => CurrentCollection.Add(f)); 
0
var newItems = DownloadedItems.Where(i => !CurrentCollection.Any(c => c.Attr == i.Attr)); 
0

Bunu şu şekilde yapabilirsiniz:

CurrentCollection.Any(x => x.bar == yourGivenValue) 
8

R.Martinho Fernandes yöntemi kullanarak ve 1 hattına dönüştürerek:

CurrentCollection.AddRange(DownloadedItems.Where(x => !CurrentCollection.Any(y => y.bar== x.bar))); 
1

Ya All

CurrentCollection 
    .AddRange(DownloadedItems.Where(x => CurrentCollection.All(y => y.bar != x.bar))); 
1

kullanarak Sen Enumerable.Except kullanabilirsiniz:

Yalnızca ilk listede görünen iki listeyi ve döndürme öğelerini karşılaştırır.

CurrentCollection.AddRange(DownloadedItems.Except(CurrentCollection)); 
İlgili konular