Ugur Yilmaz
Ugur Yilmaz

Reputation: 499

How to remove duplicates in c# list

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

Answers (2)

Scott Chamberlain
Scott Chamberlain

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

Tim Schmelter
Tim Schmelter

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

Related Questions