[英]Generic Method to get Distinct of LIST<T>
I am trying to compare (values of the properties) a instance of type in a List and eliminate duplicates. 我正在尝试比较(属性的值)列表中类型的实例,并消除重复项。 According to MSDN GetHashCode() is one of the way to compare two objects.
根据MSDN, GetHashCode()是比较两个对象的方法之一。
A hash code is intended for efficient insertion and lookup in collections that are based on a hash table.
哈希码用于在基于哈希表的集合中进行有效的插入和查找。 A hash code is not a permanent value
哈希码不是永久值
Considering that, I started writing my extension method as bellow 考虑到这一点,我开始以下面的方式编写扩展方法
public static class Linq
{
public static IEnumerable<T> DistinctObjects<T>(this IEnumerable<T> source)
{
List<T> newList = new List<T>();
foreach (var item in source)
{
if(newList.All(x => x.GetHashCode() != item.GetHashCode()))
newList.Add(item);
}
return newList;
}
}
This condition always gives me false
though the data of the object is same. 尽管对象的数据相同,但这种情况总是给我
false
的提示。
newList.All(x => x.GetHashCode() != item.GetHashCode())
Finally I would like to use it like 最后我想像
MyDuplicateList.DistinctObjects().ToList();
If comparing all fields of the object is too much, I am okay to use it like, 如果比较对象的所有字段太多,我可以这样使用它,
MyDuplicateList.DistinctObjects(x=>x.Id, x.Name).ToList();
Here I am telling compare only these two fields of those objects. 在这里,我要告诉您只比较这些对象的这两个字段。
After reading your comments I would propose this solution: 阅读您的评论后,我将提出以下解决方案:
public static IEnumerable<TSource> DistinctBy<TSource, TResult>(this IEnumerable<TSource> source, Func<TSource, TResult> selector)
{
HashSet<TResult> set = new HashSet<TResult>();
foreach(var item in source)
{
var selectedValue = selector(item);
if (set.Add(selectedValue))
yield return item;
}
}
Then you can use it like this: 然后,您可以像这样使用它:
var distinctedList = myList.DistinctBy(x => x.A);
or for multiple properties like that: 或类似的多个属性:
var distinctedList = myList.DistinctBy(x => new {x.A,x.B});
The advantage of this solution is you can exactly specify what properties should be used in distinction and you don't have to override Equals
and GetHashCode
for every object. 该解决方案的优点是,您可以精确地指定应使用哪些属性来进行区分,而不必为每个对象覆盖
Equals
和GetHashCode
。 You need to make sure that your properties can be compared. 您需要确保可以比较您的属性。
You shouldn't need to create your own custom, generic method for this. 您不需要为此创建自己的自定义通用方法。 Instead, provide a custom
EqualityComparar
for your data type: 而是为您的数据类型提供自定义
EqualityComparar
:
var myDuplicates = myList.Distinct(new MyComparer());
Where you define a custom Comparer like this: 在此处定义自定义比较器的位置如下:
public class MyComparer : IEqualityComparer<Mine>
{
public bool Equals(Mine x, Mine y)
{
if (x == null && y == null) return true;
if (x == null || y == null) return false;
return x.Name == y.Name && x.Id == y.Id;
}
public int GetHashCode(Mine obj)
{
return obj.Name.GetHashCode() ^ obj.Id.GetHashCode();
}
}
Edit: I initially had incorrect code here, this should do what you want without you having to override an Equals
operator 编辑:我最初在这里有不正确的代码,这应该做您想要的而不必重写
Equals
运算符
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.