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

时间:2014-06-27 12:37:17

标签: c# .net linq

我正在尝试消除列表中符合某种条件的所有元素。具体来说,我有一个Points列表,我需要过滤这个列表,以便从列表中删除重复的点(注意,为了这个项目的目的,一个在另一个阈值内的点被认为是相同的,因此是重复的)。我一直在尝试使用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;

我做错了什么?

3 个答案:

答案 0 :(得分:2)

代码的问题在于,您选择距离至少一个tresh以上的点。

方法的问题是“相等”必须是可交换的,这意味着pA == pBpB == pC,然后是pA == pC。如果你的条件是“tresh之内的点数是相等的”那么你就有问题了,因为我有三个点A,B和C,它们分别在tresh范围内其他,但A和C不是。

e.g。如果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

答案 1 :(得分:0)

试试这个:

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

答案 2 :(得分:0)

只需更换此行:

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

这一行

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

基本上,如果某些代码正在执行与您想要的完全相反的,请尝试反转运算符。