using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace BITKit { public static class MathE { public static int GetHash(IEnumerable self) { var hash = 0; foreach (var x in self) { if (x is not null) hash += x.GetHashCode(); } return hash; } public static bool IndexInRange(this IEnumerable self, int index) { return index >= 0 && index < self.Count(); } public static bool Equals(params T[] objs) { var a = objs.FirstOrDefault(); foreach (var b in objs) { if (a.Equals(b)) { a = b; continue; } else { return false; } } return true; } public static IEnumerable Subtract(IEnumerable a, IEnumerable b) where T : IEnumerable { List list = new(); foreach (var x in a) { if (b.Contains(x)) { } else { list.Add(x); } } return list; } public static bool TryGetIndexOf(this IEnumerable self, Func factory, out int index) { index = -1; var enumerable = self as T[] ?? self.ToArray(); for (var i = 0; i < enumerable.Length; i++) { var item = enumerable.ElementAt(i); if (!factory.Invoke(item)) continue; index = i; return true; } return false; } public static bool Contains(IEnumerable a, IEnumerable b) { foreach (var x in b) { var enumerable = a as T[] ?? a.ToArray(); if (enumerable.Contains(x)) { } else { return false; } } return true; } public static IEnumerable Combinations(IEnumerable source) { if (null == source) throw new ArgumentNullException(nameof(source)); T[] data = source.ToArray(); return Enumerable.Range(0, 1 << (data.Length) - 1) .Select(index => data.Where((v, i) => (index & (1 << i)) != 0).ToArray()); } public static IEnumerable InsertOf(this IEnumerable self, int index, T item) { if (self is null) return null; switch (self) { case List list: list.Insert(index, item); break; default: var _list = self.ToList(); _list.Insert(index, item); return _list; } return self; } public static bool TryGetSingle(this IEnumerable self, out T value) { value = default; if (self.Any()) { value = self.ElementAt(0); } return value is not null; } /// /// 组合集合中的所有元素 /// /// /// /// public static IEnumerable AllCombinations(this IEnumerable self) { var list = self.ToList(); var count = list.Count; for (var i = 0; i < count; i++) { var item = list[i]; for (var j = i + 1; j < count; j++) { yield return item; yield return list[j]; } } } public static IEnumerable SelectManyPro(this IEnumerable self, Func> factory) { return Get(self); IEnumerable Get(IEnumerable list) { var newList = new List(); foreach (var x in list) { newList.Add(x); newList.AddRange(Get(factory.Invoke(x))); } return newList.Distinct(); } } /// /// 获取集合中所有的组合,每个组合中的元素个数为输入集合的元素个数,每个元素只出现一次 /// /// /// /// public static IEnumerable> GetAllCombination(this IEnumerable self) { var list = self.ToList(); var count = list.Count; for (var i = 0; i < count; i++) { var item = list[i]; for (var j = i + 1; j < count; j++) { yield return new List { item, list[j] }; } } } /// /// Linq Distinct扩展方法,可以传入自定义比较器 /// /// /// /// /// public static IEnumerable Distinct( this IEnumerable source, Func comparer) where T : class => source.Distinct(new DynamicEqualityComparer(comparer)); /// /// 动态自定义比较器 /// /// private sealed class DynamicEqualityComparer : IEqualityComparer where T : class { private readonly Func _func; public DynamicEqualityComparer(Func func) { _func = func; } public bool Equals(T x, T y) => _func(x, y); public int GetHashCode(T obj) => 0; } } }