user3161621
user3161621

Reputation: 77

How to search inside a list for a different instance of a specific element?

So i have a list l of elements of a class called Point, and i want to remove from this list with another series of Point, im using this code:

po = new Point(x,y);
if (l.Contains(po))
l.Remove(po);

What happens is that the condition is never satisfied(i suppose cause the list doesnt contain obviously the new Point but another instance generated elsewhere) Isnt there a way for contains to just check if the element is identical even if not the actual same instance?

Upvotes: 0

Views: 65

Answers (3)

John Willemse
John Willemse

Reputation: 6698

You have to define how to compare two Point class instances, i.e. what makes them equal?

In your case, you would like them to be equal when the x and y values are both the same, right?

Take you Point class and make it inherit the IEqualityComparer<Point> interface. Implement this interface:

class Point : IEqualityComparer<Point>
{
    private int _x;
    public int x
    {
        get { return _x; }
        set { _x = value; }
    }

    private int _y;
    public int y
    {
        get { return _y; }
        set { _y = value; }
    }

    public bool Equals(Point p1, Point p2)
    {
        // Returns true if both points have the same x and y values
        // Returns false otherwise.
        if (p1 == null || p2 == null)
           return false;

        return (p1.x == p2.x) && (p1.y == p2.y);
    }

    public int GetHashCode(Point obj)
    {
        return obj.x ^ obj.y;
    }
}

Upvotes: 0

Paul Michaels
Paul Michaels

Reputation: 16695

Try:

if (l.Any(a => a.x == po.x && a.y == po.y))

To addresss the full issue, try this:

l = l.Where(a => a.x != po.x || a.y != po.y);

That should give you the remaining items without duplicates.

Upvotes: 1

Tim Schmelter
Tim Schmelter

Reputation: 460138

You either have to override Equals to get Contains working as expected or use LINQ:

l = l.Where(p => p.X != po.X || p.Y != po.Y).ToList();

Presuming that two points are equal if x and y are equal.

Here is an example with a class that overrides Equals + GethashCode:

public class Point
{
    public int X { get; set; }
    public int Y { get; set; }

    public override bool Equals(object obj)
    {
        Point p2 = obj as Point;
        if (p2 == null) return false;
        return X == p2.X && Y == p2.Y;
    }

    public override int GetHashCode()
    {
        unchecked
        {
            int hash = 17;
            hash = hash * 23 + X;
            hash = hash * 23 + Y;
            return hash;
        }
    }
}

Now you can use List.Remove which uses Equals under the hood. You don't need to check if the list contains the object:

bool contained = l.Remove(po);

Upvotes: 1

Related Questions