让我们说我有一个自定义“Point”类的列表(我知道System.Drawing中有一个,但我想我需要一个自定义类)。现在这个列表有时可以有相同的点,例如,假设它设置如下:
List<customPoint> myPoints = new List<customPoint>();
myPoints.Add(new customPoint(1,5));
myPoints.Add(new customPoint(1,5));
myPoints.Add(new customPoint(2,3));
myPoints.Add(new customPoint(4,9));
myPoints.Add(new customPoint(8,7));
myPoints.Add(new customPoint(2,3));
后来我需要做一些计算,但我不需要重复。制作一个新的独特点列表比这更优雅的方法是什么:
List<customPoint> uniquePoints = new List<customPoint>();
for(int i; i < myPoints.Count; i++)
{
Boolean foundDuplicate = false;
int tempX = myPoints[i].X;
int tempY = myPoints[i].Y;
for(int j=0; j < uniquePoints.Count; j++)
{
if((tempX == uniquePoints[0].X) && (tempY == uniquePoints[0].Y))
{
foundDuplicate = true;
break;
}
}
if(!foundDuplicate)
{
uniquePoints.Add(myPoints[i]);
}
}
我知道它很乱,但这就是为什么我在问是否有更优雅的方式。我查看了Linq“Distinct”命令,但它似乎不起作用,我猜他们的对象实例化中仍有一些东西仍然是唯一的。
答案 0 :(得分:1)
你尝试使用哪种LINQ无法正常工作?下面的代码应该这样做:
var uniquePoints = myPoints.Distinct();
答案 1 :(得分:1)
1)将这些方法添加到customPoint
public override int GetHashCode()
{
return X.GetHashCode() * 19 + Y.GetHashCode();
}
public override bool Equals(object obj)
{
var other = obj as customPoint;
return this.X == other.X && this.Y == other.Y;
}
您可以使用Linq的Distinct
方法。
var distinctPoints = myPoints.Distinct().ToList();
2)您可以使用匿名类型比较技巧,而无需覆盖任何方法。
var distinctPoints = myPoints.GroupBy(m => new { m.X, m.Y })
.Select(x => x.First())
.ToList();
3)您也可以通过撰写自定义IEqualityComparer
public class MyEqualityComparer : IEqualityComparer<customPoint>
{
public bool Equals(customPoint a, customPoint b)
{
return a.X == b.X && a.Y == b.Y;
}
public int GetHashCode(customPoint other)
{
return other.X.GetHashCode() * 19 + other.Y.GetHashCode();
}
}
var distinctPoints = myPoints.Distinct(new MyEqualityComparer()).ToList();
答案 2 :(得分:0)
Distinct
方法是一种很好的方法,但为了按照您的意愿使用它,您必须在对象上实现Equals
和GetHashCode
,或者创建一个IEqualityComparer<customPoint>
并将其传递给Distinct
方法。对于您的情况,在您的对象上实现这些方法可能是有意义的。来自文档:
默认的相等比较器Default用于比较的值 实现IEquatable<T>通用接口的类型。至 比较自定义数据类型,您需要实现此接口和 为类型提供您自己的GetHashCode和Equals方法。
答案 3 :(得分:0)
我在LinqPad中这样做了,请原谅Dump()
...但是这是实现customPoint
课程的一种方法:
void Main()
{
var myPoints = new List<customPoint>();
myPoints.Add(new customPoint(1,5));
myPoints.Add(new customPoint(1,5));
myPoints.Add(new customPoint(2,3));
myPoints.Add(new customPoint(4,9));
myPoints.Add(new customPoint(8,7));
myPoints.Add(new customPoint(2,3));
myPoints.Distinct().Dump();
}
public class customPoint {
public int X;
public int Y;
public customPoint(int x, int y){
X = x;
Y = y;
}
public override Boolean Equals(Object rhs) {
var theObj = rhs as customPoint;
if(theObj==null) {
return false;
} else {
return theObj.X == this.X && theObj.Y == this.Y;
}
}
public override int GetHashCode() {
return X ^ Y;
}
}