使用 LINQ 跨多个属性查找重复项
Posted
技术标签:
【中文标题】使用 LINQ 跨多个属性查找重复项【英文标题】:Using LINQ to find duplicates across multiple properties 【发布时间】:2011-08-01 13:58:08 【问题描述】:给定一个具有以下定义的类:
public class MyTestClass
public int ValueA get; set;
public int ValueB get; set;
如何在 MyTestClass[] 数组中找到重复值?
例如,
MyTestClass[] items = new MyTestClass[3];
items[0] = new MyTestClass ValueA = 1, ValueB = 1 ;
items[1] = new MyTestClass ValueA = 0, ValueB = 1 ;
items[2] = new MyTestClass ValueA = 1, ValueB = 1 ;
包含重复项,因为有两个 MyTestClass 对象,其中 ValueA 和 ValueB 都 = 1
【问题讨论】:
【参考方案1】:您可以通过按 ValueA 和 ValueB 对元素进行分组来查找重复项。 之后对它们进行计数,您会发现哪些是重复的。
这就是你隔离受骗者的方法:
var duplicates = items.GroupBy(i => new i.ValueA, i.ValueB)
.Where(g => g.Count() > 1)
.Select(g => g.Key);
【讨论】:
正是我想要的!你赢得了互联网。非常感谢。【参考方案2】:您可以同时使用 Jon Skeet 的 DistinctBy
和 Except
来查找重复项。他对DistinctBy
的解释见this Response。
MyTestClass[] items = new MyTestClass[3];
items[0] = new MyTestClass ValueA = 1, ValueB = 1 ;
items[1] = new MyTestClass ValueA = 0, ValueB = 1 ;
items[2] = new MyTestClass ValueA = 1, ValueB = 1 ;
MyTestClass [] distinctItems = items.DistinctBy(p => new p.ValueA, p.ValueB).ToArray();
MyTestClass [] duplicates = items.Except(distinctItems).ToArray();
它只会返回一个项目,而不是两个重复项。
【讨论】:
【参考方案3】:MyTestClass 应该实现 Equals 方法。
public bool Equals(MyTestClass x, MyTestClass y)
if (Object.ReferenceEquals(x, y)) return true;
if (Object.ReferenceEquals(x, null) ||
Object.ReferenceEquals(y, null))
return false;
return x.ValueA == y.ValueA && y.ValueB == y.ValueB;
这里有一个good article 。
之后,您可以使用“Distinct”方法获得 MyTestClass 的“干净”列表。
【讨论】:
如果 Distinct 可以工作,那么您需要做的不仅仅是实现 Equals 方法。您应该实现 IEquatable以上是关于使用 LINQ 跨多个属性查找重复项的主要内容,如果未能解决你的问题,请参考以下文章