Reputation: 1582
I have two generic Lists, one called "Featured" and the other called "Filtered".
List<Content> Featured = new List<Content>();
List<Content> Filtered = new List<Content>();
Both contain "Content" items which are simple classes like so :
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;
}
}
Any items that appear in "Filtered" but also appear in "Featured" need to be removed from "Filtered". Additionally, both lists will then be combined into a single generic list with the "Featured" items appearing first.
I know I could write a couple of foreach loops to do this but I can't help feel there must be a more elegant method using LINQ.
I am using C# 4.0.
Upvotes: 6
Views: 12127
Reputation: 50114
You're looking for the LINQ method Union
, specifically
var singleList = Featured.Union(Filtered);
This will return all the Featured
items, followed by all the Filtered
items that were not Featured
. Note that it will also remove any duplicates within a list - so if an item is Featured
twice, it will only show up once.
You do, however, need to be able to compare instances of Content
in order to do this, either by adding in implementations of Equal
and GetHashCode
or by providing an IEqualityComparer
.
Upvotes: 6
Reputation: 22945
Assuming the objects presenter in both lists are the actual same objects, you can do the following:
var totalList = Featured
.Concat(Filtered.Where(f => !Featured.Contains(f)))
.ToList()
Update
Or, using the Except method as mentioned by Mahmoud Gamal:
var totalList = Featured
.Concat(Filtered.Except(Featured))
.ToList()
Upvotes: 2
Reputation: 152521
If you have an IEqualityComparer defined you can use the Union
method:
List<Content> FeaturedAndFiltered = Featured.Union(Filtered, new MyContentComparer());
A rough implementation of MyContentComparer would be:
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();
}
}
Upvotes: 6