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}.
views:
272answers:
7
+4
A:
var x = new string[] {"One", "Two", "Three", "One", "Four", "One", "Five", "Two", "One"}.ToList();
var distinct = x.Distinct();
Climber104
2009-10-02 15:49:26
+1
A:
use distinct
List<string> l = new List<string>
{
"One","Two","Three","One","Four","One","Five","Two","One"
};
var rootcategories2 = l.Distinct();
anishmarokey
2009-10-02 15:56:24
+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
2009-10-02 16:04:28
+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
2009-10-02 16:25:00
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
2009-10-05 07:19:15
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
2009-10-05 07:21:20
You should edit your original question rather than post an answer to it. SO will prompt you to do this.
Kirk Broadhurst
2009-10-05 07:23:47
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
2009-10-05 07:25:20
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
2009-10-05 11:14:56
Thanks Konrad, answer has been edited. My bad, copy/paste error snuck in.
Steve Conlan
2009-10-05 12:22:44