Reputation: 499
I have a list consists of bunch of locations based on x and y locations and I am taking the difference of two location. So, for example I have duplications like (0,1),(1,0) and (1,2),(2,1) and (2,3),(3,2). I want to delete all those duplications from my list to achieve my goal. Is there an easy way to do this? I have been trying to build an algorithm but it is pretty hard. Because I have got like 90 locations and it is not easy to determine when it duplicates itself
Upvotes: 3
Views: 382
Reputation: 127543
The easiest solution is create a IEqualityComparer
for your point class that does not care about the order of your X
and Y
, you can then use Distinct
to get rid of the duplicates.
public class MyPoint
{
public int X { get; set; }
public int Y { get; set; }
}
public class PointComparer : IEqualityComparer<MyPoint>
{
public bool Equals(MyPoint x, MyPoint y)
{
if (ReferenceEquals(x, y)) return true;
if (ReferenceEquals(x, null)) return false;
if (ReferenceEquals(y, null)) return false;
return (x.X == y.X && x.Y == y.Y) ||
(x.X == y.Y && x.Y == y.X);
}
public int GetHashCode(MyPoint obj)
{
return (obj?.X.GetHashCode() ?? 0) ^ (obj?.Y.GetHashCode() ?? 0);
}
}
class Program
{
static void Main()
{
List<MyPoint> data = GetDataFromSomewhere();
var singularData = data.Distinct(new PointComparer()).ToList();
}
}
Upvotes: 7
Reputation: 460098
I would use Enumerable.Distinct
with a custom comparerer for the logic:
public class OppositeLocationsEqualComparer : IEqualityComparer<Location>
{
public bool Equals(Location l1, Location l2)
{
if (object.ReferenceEquals(l1, l2)) return true;
if (l1 == null || l2 == null) return false;
return (l1.X == l2.X && l1.Y == l2.Y) || (l1.X == l2.Y && l1.Y == l2.X);
}
public int GetHashCode(Location l)
{
if(l == null) return int.MinValue;
return Math.Abs(l.X - l.Y);
}
}
Now you can use Enumerable.Distinct
(and many other LINQ methods) with this comparer:
List<Location> uniqueLocations = locationList
.Distinct(new OppositeLocationsEqualComparer())
.ToList();
Upvotes: 2