Linq is nice. Usable. Readable. But … Distinct.
In short. There is no appropriate distinct in Linq.
What I mean “Appropriate” ?. Something like myList.Distinc(x=>x.id).
And there is nothing like that.
Possible solutions:
1. Group by
var queryLastNames =
from student in students
group student by student.LastName into newGroup
orderby newGroup.Key
select newGroup;
from student in students
group student by student.LastName into newGroup
orderby newGroup.Key
select newGroup;
2. Morelinq library
- it is a Nuget package
- there is:
- myList.DistincBy(x=>x.id)
- or myList.DistinctBy(x=>new {x.Id1,x.Id2,x.Id3)
- it is from year 2009 … and it is still not implemented in Linq …
- Thank you Pranay Rana
3. You can create your own TryToDictionary method
private static Dictionary<T, K> TryToDictionary<T,K>(
Func<K,T> getId,
IEnumerable<K> list)
{
var result = new Dictionary<T, K>();
foreach (var item in list)
{
if (result.ContainsKey(getId(item))) continue;
result.Add(getId(item), item);
}
return result;
}
private static List<K> TryToUniqueList<T, K>(Func<K, T> getId, IEnumerable<K> list)
{
return TryToDictionary<T,K>(getId,list).Select(x => x.Value).ToList();
}
Func<K,T> getId,
IEnumerable<K> list)
{
var result = new Dictionary<T, K>();
foreach (var item in list)
{
if (result.ContainsKey(getId(item))) continue;
result.Add(getId(item), item);
}
return result;
}
private static List<K> TryToUniqueList<T, K>(Func<K, T> getId, IEnumerable<K> list)
{
return TryToDictionary<T,K>(getId,list).Select(x => x.Value).ToList();
}
4. Use original distinct with IEqualityComparer<T>
4.1 Implement IEqualityComparer<T>
.. Just if You really need one ...4.2 But You can create a lambda version ! :-)
.. thank you Ruben Bartelink and Stackowerflow !public class LambdaEqualityComparer<T> : IEqualityComparer<T>
{
readonly Func<T, T, bool> _comparer;
readonly Func<T, int> _hash;
public LambdaEqualityComparer(Func<T, T, bool> comparer)
: this(comparer, t => 0)
{
}
public LambdaEqualityComparer(Func<T, T, bool> comparer, Func<T, int> hash)
{
_comparer = comparer;
_hash = hash;
}
public bool Equals(T x, T y)
{
return _comparer(x, y);
}
public int GetHashCode(T obj)
{
return _hash(obj);
}
}
then you can use it like this
myList.Distinct(new LambdaEqualityComparer<MyClass>((x,y)=>x.Property1.Equals(y.Property1)));
No comments:
Post a Comment