2011-06-13 24 views
25

Básicamente, ¿cómo lo hago para que pueda hacer algo similar a: CurrentCollection.Contains(...), excepto al comparar si la propiedad del elemento ya está en la colección?¿Agregar elementos a una colección si la colección NO la contiene comparando una propiedad de los elementos?

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? 

Respuesta

34

Usted empezar por encontrar qué elementos no están ya en la colección:

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

Y luego hay que añadirlas:

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

Tenga en cuenta que la primera operación puede tener la complejidad cuadrática si el tamaño de DownloadedItems está cerca del tamaño de CurrentCollection. Si eso termina causando problemas (medir primero!), Se puede utilizar un HashSet para traer la complejidad hasta lineal:

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

Usted puede llamar al método Any y pasar un valor a comparar con lo que sea propiedad del tipo de objeto en la colección

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

una solución más completa podría ser:

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

Podrías hacerlo así:

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

Utilizando el método R.Martinho Fernandes y la conversión a la línea 1:

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

O usando All

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

puede utilizar Enumerable.Except:

Comparará las dos listas y los elementos devueltos que aparecen solo en la primera lista.

CurrentCollection.AddRange(DownloadedItems.Except(CurrentCollection)); 
Cuestiones relacionadas