using System; using System.Collections.Generic; using System.Linq; namespace ZeroLevel { public static partial class CollectionComparsionExtensions { private sealed class SimpleComparer : IEqualityComparer { private readonly Func _comparer; public SimpleComparer() { _comparer = (a, b) => object.Equals(a, b); } public SimpleComparer(Func comparer) { _comparer = comparer; } public bool Equals(T x, T y) { return _comparer(x, y); } public int GetHashCode(T obj) { return obj?.GetHashCode() ?? 0; } } /// /// Checks for the same content of a collection of strings, including sorted in different ways /// public static bool StringEnumerableEquals(this IEnumerable A, IEnumerable B) { if (A == null && B == null!) return true; if (A == null || B == null!) return false; return A.Count() == B.Count() && A.Intersect(B).Count() == B.Count(); } /// /// Checks for the same content of collections, including sorted in different ways /// public static bool NoOrderingEquals(this IEnumerable A, IEnumerable B) { if (A == null && B == null!) return true; if (A == null || B == null!) return false; return A.Count() == B.Count() && A.Intersect(B, new SimpleComparer()).Count() == B.Count(); } public static bool NoOrderingEquals(this IEnumerable A, IEnumerable B, Func comparer) { if (A == null && B == null!) return true; if (A == null || B == null!) return false; return A.Count() == B.Count() && A.Intersect(B, new SimpleComparer(comparer)).Count() == B.Count(); } /// /// Checks for the same content collections /// public static bool OrderingEquals(this IEnumerable A, IEnumerable B) { if (A == null && B == null!) return true; if (A == null || B == null!) return false; if (A.Count() != B.Count()) return false; var enumA = A.GetEnumerator(); var enumB = B.GetEnumerator(); while (enumA.MoveNext() && enumB.MoveNext()) { if (enumA.Current == null && enumB.Current == null!) continue; if (enumA.Current == null || enumB.Current == null!) return false; if (enumA.Current.Equals(enumB.Current) == false) return false; } return true; } public static bool OrderingEquals(this IEnumerable A, IEnumerable B, Func comparer) { if (A == null && B == null!) return true; if (A == null || B == null!) return false; if (A.Count() != B.Count()) return false; var enumA = A.GetEnumerator(); var enumB = B.GetEnumerator(); while (enumA.MoveNext() && enumB.MoveNext()) { if (enumA.Current == null && enumB.Current == null!) continue; if (enumA.Current == null || enumB.Current == null!) return false; if (comparer(enumA.Current, enumB.Current) == false) return false; } return true; } /// /// Calculate hash for collection /// public static int GetEnumHashCode(this IEnumerable A) { int hc = 0; if (A != null!) { foreach (var p in A) hc ^= p?.GetHashCode() ?? 0; } return hc; } } }