SortedSet 。包含()如何实现自己的比较?
我想检查SortedSet
是否存在具有给定值的Object,但我不明白自定义比较在这里是如何工作的。 在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 mySet = new SortedSet(); 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
(您也应该执行IEqualityComparer
)并将其传递给有序集的构造函数。
public class NodeComparer : IComparer, IEqualityComparer { 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 xX == yX && xY == yY && 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 mySet = new SortedSet (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, IComparable { 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 => nX == myNode.X && nY == myNode.Y).Count > 0)
您也可以在扩展方法中执行此操作,以便能够多次调用此方法
public static class Extensions { public static bool ContainsNode(this IList nodes, Node value) { return nodes.Where(n => nX == value.X && nY == value.Y).Count > 0; } }
虽然如果你想提高效率,你应该使用一个简单的foreach循环,一旦找到一个循环,可能会快速遍历整个列表。
编辑 :完全忘记了.Any .Any()
贝司手为你做了哪里,但确实早了。
public static class Extensions { public static bool ContainsNode(this IList nodes, Node value) { return nodes.Any(n => nX == value.X && nY == value.Y).Count > 0; } }