Click here to Skip to main content
6,595,444 members and growing! (20,232 online)
Email Password   helpLost your password?
Platforms, Frameworks & Libraries » LINQ » General     Intermediate License: The Code Project Open License (CPOL)

LINQ Extension Method to Return a Unique List Based on a Key

By Stephen Inglish

LINQ Extension method to return a Unique List based on a key
C#, LINQ, Dev
Posted:5 Dec 2008
Views:10,667
Bookmarked:6 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
4 votes for this article.
Popularity: 2.21 Rating: 3.67 out of 5

1
1 vote, 25.0%
2

3
1 vote, 25.0%
4
2 votes, 50.0%
5

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);
/// <summary>
/// Takes a List of type <typeparamref name="T"/> 
/// and a function as the key selector and returns a unique list of type 
/// <typeparamref name="T"/>
/// from that list
/// </summary>
/// <typeparam name="KEY">The type of the KEY.</typeparam>
/// <typeparam name="T"></typeparam>
/// <param name="InputList">The input list.</param>
/// <param name="func">The func.</param>
/// <returns></returns>
/// <example><code>List&lt;T&gt; uniqueList = 
/// 	nonUniqueList.Unique(key=>key.ID);</code></example>
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; }

    // Convert the inputList to a dictionary based on the key selector provided
    Dictionary<KEY, T> uniqueDictionary = new Dictionary<KEY, T>();
    InputList.ForEach(item =>
    {
        // Use the key selector function to retrieve the key
        KEY k = func.Invoke(item);

        // Check the dictionary for that key
        if (!uniqueDictionary.ContainsKey(k))
        {
            // Add that item to the dictionary 
            uniqueDictionary.Add(k, item);
        }
    });

    // Get the enumerator of the dictionary
    Dictionary<KEY, T>.Enumerator e = uniqueDictionary.GetEnumerator();

    List<T> uniqueList = new List<T>();
    while (e.MoveNext())
    {
        // Enumerate through the dictionary keys and pull out 
        // the values into a unique list
        uniqueList.Add(e.Current.Value);
    }

    // return the unique list
    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

  • v1.0 12/05/2008

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Stephen Inglish


Member

Occupation: Software Developer
Company: Sogeti USA
Location: United States United States

Other popular LINQ articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 19 of 19 (Total in Forum: 19) (Refresh)FirstPrevNext
GeneralSuggestions Pinmembertonyt16:56 5 Dec '08  
GeneralI give up Pinmembertonyt17:02 5 Dec '08  
GeneralRe: I give up PinmvpColin Angus Mackay1:02 6 Dec '08  
GeneralRe: I give up Pinmembertonyt16:26 6 Dec '08  
GeneralRe: I give up PinmvpColin Angus Mackay1:37 7 Dec '08  
GeneralRe: I give up Pinmembertonyt22:43 8 Dec '08  
GeneralRe: I give up PinmemberGünther M. FOIDL3:12 6 Dec '08  
GeneralRe: I give up Pinmembertonyt16:27 6 Dec '08  
Answer< and > PinmemberTobiasP1:25 16 Dec '08  
GeneralRe: Suggestions PinmemberGünther M. FOIDL3:15 6 Dec '08  
GeneralRe: Suggestions [modified] Pinmembertonyt16:34 6 Dec '08  
GeneralRe: Suggestions PinmemberGünther M. FOIDL2:49 7 Dec '08  
GeneralDistinct and Intersect PinsupporterMark Nischalke14:50 5 Dec '08  
GeneralRe: Distinct and Intersect PinmemberGünther M. FOIDL3:21 6 Dec '08  
GeneralRe: Distinct and Intersect PinsupporterMark Nischalke4:30 6 Dec '08  
GeneralRe: Distinct and Intersect PinmemberGünther M. FOIDL5:32 6 Dec '08  
GeneralImprovement [modified] PinmemberGünther M. FOIDL11:52 5 Dec '08  
GeneralRe: Improvement PinmemberJean-Paul Mikkers13:04 5 Dec '08  
GeneralConvert extension from List to IEnumerable<T> PinmemberMichael Lee Yohe7:13 19 Dec '08  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 5 Dec 2008
Editor: Deeksha Shenoy
Copyright 2008 by Stephen Inglish
Everything else Copyright © CodeProject, 1999-2009
Web16 | Advertise on the Code Project