Introduction
This article is about a handy LINQ extension method that will take a List<T>
and a key selector, and return a unique List<T>
based on that key.
Background
I had a need to use an in-code way of refining a List<T>
so there was no duplication on a key. I developed this handy LINQ Extension to do it for me.
Using the Code
Use this method on any List<T>
. This is an extension method, so it has to be put in a static
class.
Example
List<MyClass> classList;
Assuming classList
is populated with values...
List<MyClass> filteredList = classList.Unique(cl => cl.SomeKeyProperty);
public static List<T> Unique<KEY, T>(this List<T> InputList, Func<T, KEY> func)
{
if (func == null)
throw new ArgumentNullException("Key selector function cannot be null");
if (InputList == null)
{ return null; }
if (InputList.Count == 0)
{ return InputList; }
Dictionary<KEY, T> uniqueDictionary = new Dictionary<KEY, T>();
InputList.ForEach(item =>
{
KEY k = func.Invoke(item);
if (!uniqueDictionary.ContainsKey(k))
{
uniqueDictionary.Add(k, item);
}
});
Dictionary<KEY, T>.Enumerator e = uniqueDictionary.GetEnumerator();
List<T> uniqueList = new List<T>();
while (e.MoveNext())
{
uniqueList.Add(e.Current.Value);
}
return uniqueList;
}
Points of Interest
While LINQ has a .ToDictionary()
extension method, if you have a List<T>
that contains items that aren't unique, .ToDictionary()
will throw an exception indicating that a key already exists in the dictionary. So I had to write the code above to only add items to the dictionary if they didn't already exist.
History