如何根据自定义条件使用LINQ删除列表中的重复元素

本文关键字:列表 删除列 元素 删除 LINQ 何根 自定义 条件 | 更新日期: 2023-09-27 18:10:37

我试图消除列表中所有符合特定条件的元素。具体来说,我有一个点列表,我需要过滤这个列表,这样重复的点就应该从列表中删除(注意,为了这个项目的目的,在另一个点的一定阈值内的点被认为是相同的,因此是重复的)。我一直在尝试使用LINQ来做到这一点,但我一直有应该被淘汰的点(根据我的条件)。我的代码如下:

var fingers = from p1Index in Enumerable.Range(0, fingAux.Count())
              from p2 in fingAux.Skip(p1Index + 1)
              let p1 = fingAux.ElementAt(p1Index)
              where (p1.X > p2.X + tresh) || (p1.X < p2.X - tresh)
              select p1;

我做错了什么?

如何根据自定义条件使用LINQ删除列表中的重复元素

您的代码的问题是您选择的点与至少有一个点的距离大于tresh

您的方法的问题是"相等性"必须是可交换的,这意味着如果pA == pBpB == pC,那么pA == pC。如果你的条件是"tresh内的点彼此相等",那么你就有问题了,因为我可以有三个点A, B和C,它们在tresh内彼此,但A和C不是。

。如果tresh是5,并且我有点A=3, B=7和C=9,那么A和B是"相等的",B和C是"相等的",但A和C不是。

另一种选择是将每个点"四舍五入"到最近的tresh并将它们分组,从每组中选择第一个:

fingAux.GroupBy(p => Math.Round(p1.X / tresh))  // assuming X and/or tresh are floating-point
       .Select(g => g.First());   // take the first point of each group

试试这个:

var filtered = from p in fingAux
           where !(fingAux.Any(f1 => p.X < (f1.X + tresh)) select p

只需替换这一行:

where (p1.X > p2.X + tresh) || (p1.X < p2.X - tresh)

和这一行

where (p1.X < p2.X + tresh) && (p1.X > p2.X - tresh))

基本上,如果一些代码的与您想要的完全相反,请尝试将操作符反转