Reputation: 33
I'm trying to eliminate all the elements in a list that obey a certain condition. Specifically, I have a list of Points and I need to filter this list such that duplicate points should be removed from the list (Note that for the purpose of this project a point that is within a certain threshold of another is considered to be the same, and hence is a duplicate). I've been trying to use LINQ to do this but I keep having Points that should have been eliminated (according to my conditions). My code is as follows:
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;
What am I doing wrong?
Upvotes: 0
Views: 193
Reputation: 495
Simply replace this line:
where (p1.X > p2.X + tresh) || (p1.X < p2.X - tresh)
with this line
where (p1.X < p2.X + tresh) && (p1.X > p2.X - tresh))
Basically, if some code is doing the exact opposite of what you want, try inverting the operators.
Upvotes: 0
Reputation: 152566
The problem with your code is that you're selecting points that are more than tresh
away from at least one point.
The problem with your method is "equality" must be commutative, meaning if pA == pB
and pB == pC
, then pA == pC
. If your condition is "points within tresh
of each other are equal" then you have an issue, since I could have three points A, B, and C, that are within tresh
of each other, but A and C are not.
e.g. if tresh
is 5, and I have points A=3, B=7, and C=9, then A and B are "equal", B and C are "equal", but A and C are not.
Another option would be to "round" each point to the nearest tresh
and group them, selecting the first from each group:
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
Upvotes: 2
Reputation: 4654
Try this:
var filtered = from p in fingAux
where !(fingAux.Any(f1 => p.X < (f1.X + tresh)) select p
Upvotes: 0