2012-07-09 12 views
6

Ho due elenchi generici, uno denominato "In primo piano" e l'altro chiamato "Filtrato".Confronta due elenchi generici e rimuovi i duplicati

List<Content> Featured = new List<Content>(); 
List<Content> Filtered = new List<Content>(); 

Entrambi contengono elementi di "contenuto", che sono semplici classi in questo modo:

public class Content 
{ 
    public long ContentID { get; set;} 
    public string Title { get; set; } 
    public string Url { get; set; } 
    public string Image { get; set; } 
    public string Teaser { get; set; } 

    public Content(long contentId, string title, string url, string image, string teaser) 
    { 
     ContentID = contentId; 
     Title = title; 
     Url = url; 
     Image = image; 
    } 
} 

Tutti gli elementi che appaiono in "filtrati", ma appaiono anche in "vetrina" devono essere rimossi dal "filtrata" . Inoltre, entrambe le liste verranno quindi riunite in un unico elenco generico con gli elementi "In primo piano" che appaiono per primi.

So che potrei scrivere un paio di cicli foreach per farlo, ma non posso fare a meno di sentire che ci deve essere un metodo più elegante con LINQ.

Sto usando C# 4.0.

+0

Quindi, 'Featured' dovrebbe apparire nella sua interezza, e quindi' Filtrato', ma con qualsiasi elemento di 'Featured' rimosso? –

+0

Sì sì giusto :) –

+1

Dai un'occhiata a: http://stackoverflow.com/a/2060093/100283. Non è Linq ma è un modo semplice per confrontare i due oggetti. –

risposta

6

Se si dispone di un IEqualityComparer definito è possibile utilizzare il metodo Union:

List<Content> FeaturedAndFiltered = Featured.Union(Filtered, new MyContentComparer()); 

Un'implementazione approssimativa di MyContentComparer sarebbe:

public class ContentEqualityComparer : IEqualityComparer<Content> 
{ 

    public bool Equals(Content c1, Content c2) 
    { 
     return (c1.ContentID == c2.ContentID); 
    } 


    public int GetHashCode(Content c) 
    { 
     return c.ContentID.GetHashCode(); 
    } 

} 
2

Supponendo che gli oggetti Presenter in entrambe le liste sono gli stessi attuale oggetti, è possibile effettuare le seguenti operazioni:

var totalList = Featured 
    .Concat(Filtered.Where(f => !Featured.Contains(f))) 
    .ToList() 

Aggiornamento

Oppure, utilizzando il metodo di eccezione come detto da Mahmoud Gamal:

var totalList = Featured 
    .Concat(Filtered.Except(Featured)) 
    .ToList() 
6

Stai cercando il metodo di LINQ Union, specificamente

var singleList = Featured.Union(Filtered); 

Ciò restituirà tutte le Featured elementi, seguito da tutti gli elementi Filtered che non erano Featured. Nota che sarà anche rimuovere tutti i duplicati all'interno di un elenco - quindi se un elemento è Featured due volte, verrà visualizzato solo una volta.

Tu fai, però, hanno bisogno di essere in grado di confrontare istanze di Content al fine di fare questo, o aggiungendo in implementazioni di Equal e GetHashCode o fornendo un IEqualityComparer.