Сравнение двух общих списков и удаление дубликатов

у меня есть два общих списка, один называется "рекомендуемые", а другой называется "отфильтрованный".

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

оба содержат элементы "Content", которые являются простыми классами, такими как :

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

любые элементы, которые появляются в "Filtered", но также появляются в" Featured", должны быть удалены из"Filtered". Кроме того, оба списка затем будут объединены в один общий список с "признакам" элементы появляются первыми.

Я знаю, что могу написать пару циклов foreach для этого, но я не могу не чувствовать, что должен быть более элегантный метод с использованием LINQ.

Я использую C# 4.0.

3 ответов


Если у вас определен IEqualityComparer, вы можете использовать Union способ:

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

грубая реализация MyContentComparer будет:

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();
    }

}

вы ищете метод LINQ Union, в частности

var singleList = Featured.Union(Filtered);

это вернет все Featured элементы, а затем все Filtered элементы, которые не были Featured. Обратите внимание, что это будет и удалить все дубликаты внутри список-так что если элемент Featured дважды, он будет отображаться только после.

вы, однако, должны быть в состоянии сравнить экземпляров Content для того, чтобы сделать это, либо путем добавления в реализации Equal и GetHashCode, или путем предоставления IEqualityComparer.


предполагая, что объекты presenter в обоих списках являются фактическими же объектами, вы можете сделать следующее:

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

обновление

или, используя метод Except, как упоминалось Махмудом Гамалем:

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