排序集<>。包含()如何实现自己的比较?



我想检查给定值的对象是否存在于SortedSet<>中,但我不明白这里的自定义比较是如何工作的。在List<>.Exists()中,我可以使用lambda,但我不能在那里这样做,而且我没有得到整个接口的东西,而msdn说我需要覆盖int返回函数。

public class Node
{
    public int X, Y;
    public int rand;
    public Node(int x, int y, int r)
    { X = x; Y = y; rand = r; }
}
class Program
{
    static void Main(string[] args)
    {
        SortedSet<Node> mySet = new SortedSet<Node>();
        mySet.Add(new Node(1, 2, 90));
        Node myNode = new Node(1, 2, 50);
        // I want this to check if X and Y are the same
        if (mySet.Contains(myNode, interfaceThing))
            Console.WriteLine("Sth is already on that (X, Y) position");      
    }
}

有什么简单的方法吗?

您有两个选择,创建一个实现IComparer<Node>的类(您也应该执行IEqualityComparer<Node>)并将其传递给排序集的构造函数。

public class NodeComparer : IComparer<Node>, IEqualityComparer<Node>
{
    public int Compare(Node node1, Node node2)
    {
        //Sorts by X then by Y
        //perform the X comparison
        var result = node1.X.CompareTo(node2.X);
        if (result != 0)
            return result;
        //Perform the Y Comparison
        return node1.Y.CompareTo(node2.Y);
    }
    public bool Equals(Node x, Node y)
    {
        if (ReferenceEquals(x, y)) return true;
        if (ReferenceEquals(x, null)) return false;
        if (ReferenceEquals(y, null)) return false;
        if (x.GetType() != y.GetType()) return false;
        return x.X == y.X && x.Y == y.Y && x.rand == y.rand;
    }
    public int GetHashCode(Node obj)
    {
        unchecked
        {
            var hashCode = obj.X;
            hashCode = (hashCode * 397) ^ obj.Y;
            hashCode = (hashCode * 397) ^ obj.rand;
            return hashCode;
        }
    }
}
public class Node
{
    public int X, Y;
    public int rand;
    public Node(int x, int y, int r)
    { X = x; Y = y; rand = r; }
}
class Program
{
    static void Main(string[] args)
    {
        SortedSet<Node> mySet = new SortedSet<Node>(new NodeComparer());
        mySet.Add(new Node(1, 2, 90));
        Node myNode = new Node(1, 2, 50);
        // I want this to check if X and Y are the same
        if (mySet.Contains(myNode, interfaceThing))
            Console.WriteLine("Sth is already on that (X, Y) position");      
    }
}

或者让Node自己实现它需要的相关方法。

public class Node : IEquatable<Node>, IComparable<Node>
{
    public int X, Y;
    public int rand;
    public Node(int x, int y, int r)
    { X = x; Y = y; rand = r; }
    public bool Equals(Node other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return X == other.X && Y == other.Y && rand == other.rand;
    }
    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((Node)obj);
    }
    public override int GetHashCode()
    {
        unchecked
        {
            var hashCode = X;
            hashCode = (hashCode*397) ^ Y;
            hashCode = (hashCode*397) ^ rand;
            return hashCode;
        }
    }
    public int CompareTo(Node other)
    {
        //First order by X then order by Y then order by rand
        var result = X.CompareTo(other.X);
        if (result != 0)
            return result;
        result = Y.CompareTo(other.Y);
        if (result != 0)
            return result;
        return rand.CompareTo(other.rand);
    }
}

一个简单的方法是使用一些linq

if(myNode.Where(n => n.X == myNode.X && n.Y == myNode.Y).Count > 0)

您也可以在扩展方法中这样做,以便能够多次调用此

public static class Extensions
{
    public static bool ContainsNode(this IList<Node> nodes, Node value)
    {
        return nodes.Where(n => n.X == value.X && n.Y == value.Y).Count > 0;
    }
}

如果你想要更有效率,你应该使用一个简单的foreach循环来代替,这样可以在找到一个循环后快速遍历整个列表。

编辑:完全忘记了.Any()基本上为你做了Where,但提前切断了。

public static class Extensions
{
    public static bool ContainsNode(this IList<Node> nodes, Node value)
    {
        return nodes.Any(n => n.X == value.X && n.Y == value.Y).Count > 0;
    }
}

最新更新