tags:

views:

272

answers:

7

I have a list of items like so {One,Two,Three,One,Four,One,Five,Two,One} and I need a query that takes that list and generates a list based on only unique items, so the list returned would be {One,Two,Three,Four,Five}.

+16  A: 

Use the Distinct operator:

var unique = list.Distinct();
CMS
+5  A: 

The Distinct operator. There's an example at MSDN.

http://msdn.microsoft.com/en-us/library/bb348436.aspx

Austin Salonen
+4  A: 
        var x = new string[] {"One", "Two", "Three", "One", "Four", "One", "Five", "Two", "One"}.ToList();
        var distinct = x.Distinct();
Climber104
+1  A: 

use distinct

    List<string> l = new List<string>
    {
        "One","Two","Three","One","Four","One","Five","Two","One"
    };

    var rootcategories2 = l.Distinct();
anishmarokey
+1  A: 

Aside from Distinct, as others have mentioned, you can also use a HashSet:

List<string> distinct = new HashSet<string>(list).ToList();

If you're using LINQ, though, go with Distinct.

Chris Doggett
+2  A: 

It's worth noting Distinct() will use the default means of determining equality, which might not suit you if your list contains complex objects rather than primitives.

There is an overload that allows you to specify an IEqualityComparer for providing custom equality logic.

More details on how Distinct determines if two items are equal: http://msdn.microsoft.com/en-us/library/ms224763.aspx

batwad
A: 

Thanks for all your answers, I guess I mis-posed my question slightly. What I really have is a complex class, on which I want the comparison (for Distinct) based on a particular member of the class.

class ComplexClass
{
    public string Name{ get; set; }
    public string DisplayName{ get; set; }
    public int ComplexID{ get; set; }
}

List<ComplexClass> complexClassList = new List<ComplexClass>();

complexClassList.Add(new ComplexClass(){Name="1", DisplayName="One", ComplexID=1});
complexClassList.Add(new ComplexClass(){Name="2", DisplayName="Two", ComplexID=2});
complexClassList.Add(new ComplexClass(){Name="3", DisplayName="One", ComplexID=1});

// This doesn't produce a distinct list, since the comparison is Default
List<ComplexClass) uniqueList = complexClassList.Distinct();

class ComplexClassNameComparer : IEquatable<ComplexClass>
{
    public override bool Equals(ComplexClass x, ComplexClass y)
    {
        return (x.To.DisplayName == y.To.DisplayName);
    }

    public override int GetHashCode(ComplexClass obj)
    {
        return obj.DisplayName.GetHashCode();
    }
}

// This does produce a distinct list, since the comparison is specific
List<ComplexClass) uniqueList = Enumerable.Distinct(complexClassList , new ComplexClassNameComparer());
Steve Conlan
Thanks to those who already pointed that out, and for the suggestions of HashSets. Using Distinct with a custom IEqualityComparer<TSource> comparer worked.
Steve Conlan
You should edit your original question rather than post an answer to it. SO will prompt you to do this.
Kirk Broadhurst
Your `ComplexClassComparer` has a discrepancy between the implementations of `Equals` and `GetHashCode`. Make sure the returned values are always consistent, which isn’t obvious at the moment. `GetHashCode` should rather return `obj.To.DisplayName.GetHashCode()`.
Konrad Rudolph
Thanks Kirk, however, in this case, I felt it more accurate to answer instead of editing the question and invalidating all the answers.
Steve Conlan
Thanks Konrad, answer has been edited. My bad, copy/paste error snuck in.
Steve Conlan