[英]Getting List of Objects that occurs exaclty twice in a list
我有一個List<CustomPoint> points;
其中包含近百萬個對象。 從這個列表中我想得到恰好發生兩次的對象列表。 最快的方法是什么? 我也會對非Linq選項感興趣,因為我可能也必須在C ++中這樣做。
public class CustomPoint
{
public double X { get; set; }
public double Y { get; set; }
public CustomPoint(double x, double y)
{
this.X = x;
this.Y = y;
}
}
public class PointComparer : IEqualityComparer<CustomPoint>
{
public bool Equals(CustomPoint x, CustomPoint y)
{
return ((x.X == y.X) && (y.Y == x.Y));
}
public int GetHashCode(CustomPoint obj)
{
int hash = 0;
hash ^= obj.X.GetHashCode();
hash ^= obj.Y.GetHashCode();
return hash;
}
}
基於這個答案,我試過,
list.GroupBy(x => x).Where(x => x.Count() = 2).Select(x => x.Key).ToList();
但是這會在新列表中給出零對象。 有人可以指導我嗎?
您應該在類本身而不是PointComparer中實現Equals和GetHashCode
要使代碼正常工作,您需要將PointComparer
的實例作為第二個參數傳遞給GroupBy
。
這個方法適合我:
public class PointCount
{
public CustomPoint Point { get; set; }
public int Count { get; set; }
}
private static IEnumerable<CustomPoint> GetPointsByCount(Dictionary<int, PointCount> pointcount, int count)
{
return pointcount
.Where(p => p.Value.Count == count)
.Select(p => p.Value.Point);
}
private static Dictionary<int, PointCount> GetPointCount(List<CustomPoint> pointList)
{
var allPoints = new Dictionary<int, PointCount>();
foreach (var point in pointList)
{
int hash = point.GetHashCode();
if (allPoints.ContainsKey(hash))
{
allPoints[hash].Count++;
}
else
{
allPoints.Add(hash, new PointCount { Point = point, Count = 1 });
}
}
return allPoints;
}
這樣稱呼:
static void Main(string[] args)
{
List<CustomPoint> list1 = CreateCustomPointList();
var doubles = GetPointsByCount(GetPointCount(list1), 2);
Console.WriteLine("Doubles:");
foreach (var point in doubles)
{
Console.WriteLine("X: {0}, Y: {1}", point.X, point.Y);
}
}
private static List<CustomPoint> CreateCustomPointList()
{
var result = new List<CustomPoint>();
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
result.Add(new CustomPoint(i, j));
}
}
result.Add(new CustomPoint(1, 3));
result.Add(new CustomPoint(3, 3));
result.Add(new CustomPoint(0, 2));
return result;
}
CustomPoint
實現:
public class CustomPoint
{
public double X { get; set; }
public double Y { get; set; }
public CustomPoint(double x, double y)
{
this.X = x;
this.Y = y;
}
public override bool Equals(object obj)
{
var other = obj as CustomPoint;
if (other == null)
{
return base.Equals(obj);
}
return ((this.X == other.X) && (this.Y == other.Y));
}
public override int GetHashCode()
{
int hash = 23;
hash = hash * 31 + this.X.GetHashCode();
hash = hash * 31 + this.Y.GetHashCode();
return hash;
}
}
它打印:
Doubles:
X: 0, Y: 2
X: 1, Y: 3
X: 3, Y: 3
正如您在GetPointCount()
看到的,我為每個唯一的CustomPoint
創建一個字典(通過哈希)。 然后我插入一個PointCount
對象,其中包含一個以Count
為1開始的CustomPoint
的引用,每次遇到相同的點時, Count
都會增加。
最后,在GetPointsByCount
我返回CustomPoint
字典中的S其中PointCount.Count == count
,你的情況2。
還請注意我更新了GetHashCode()
方法,因為你的方法為點(1,2)和(2,1)返回相同的方法。 如果您確實需要,請隨意恢復自己的哈希方法。 您必須測試散列函數,因為很難將兩個數字唯一地散列為一個。 這取決於使用的數字范圍,因此您應該實現適合您自己需要的哈希函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.