Distinct in linq?
I am wondering how can I achieve this?
I want to get only distinct names from a collection of objects
MyObject a = new Object();
a.Name = 'One';
a.Value = '10';
MyObject b = new Object();
b.Name = 'One';
b.Value = '15';
MyObject c = new Object();
c.Name = 'Two';
c.Value = '10';
So I want to get only back the name. I don't care about the value in this case just the name.
So I tried
//add all the objects to a collection.
myCollectio开发者_高级运维n.Disinct()..Select(x => new MyClassToStore() {Text = x.Name, Value = x.Name}).ToList());
However I need to do distinct at the property level not at the object level. So I want back "One" and "Two". Right now I get "One", "One" and "Two" back.
I see a library called morelinq but I not sure if I should use it as it still in beta and does not seem to be developed on anymore.
Plus a whole library for one extract query I am not sure if it is worth it.
Maybe something like this can help?
var distinctItems = items
.GroupBy(x => x.PropertyToCompare)
.Select(x => x.First());
This populates both the Text and Value fields:
myCollection.Select(x => x.Name).Distinct()
.Select(x => new MyClassToStore { Text = x, Value = x }).ToList();
If you just want back distinct names, you can use:
myCollection.Select(x => x.Name).Distinct().ToList();
You can implement your class so the linq distinct operator does not use the default equality comparer.
class YourClass:IEquatable<YourClass>
{
... Your implementation details. ...
public bool Equals(YourClass other)
{
if (Object.Equals(this, other))
{
return true;
}
else
{
if(Name == other.Name && Value == other.Value)
{
return true;
}
else
{
return false;
}
}
}
public override int GetHashCode()
{
return Name.GetHashCode() ^ Value.GetHashCode();
}
}
Personally I suggest you override operator == and != and determine how and why an object is unique there. Then use the Distinct() call on the collection.
You do have to be careful with null values, see Microsoft's Guidelines for Overloading Equals() and Operator == (C# Programming Guide).
精彩评论