Net.Like.Xue.Tokyo/Assets/BITKit/Core/Mathematics/MathE.cs

215 lines
6.3 KiB
C#
Raw Normal View History

2024-11-03 16:42:23 +08:00
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace BITKit
{
public static class MathE
{
public static int GetHash<T>(IEnumerable<T> self)
{
var hash = 0;
foreach (var x in self)
{
if (x is not null)
hash += x.GetHashCode();
}
return hash;
}
public static bool IndexInRange<T>(this IEnumerable<T> self, int index)
{
return index >= 0 && index < self.Count();
}
public static bool Equals<T>(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<T> Subtract<T>(IEnumerable<T> a, IEnumerable<T> b) where T : IEnumerable
{
List<T> list = new();
foreach (var x in a)
{
if (b.Contains(x))
{
}
else
{
list.Add(x);
}
}
return list;
}
public static bool TryGetIndexOf<T>(this IEnumerable<T> self, Func<T, bool> 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<T>(IEnumerable<T> a, IEnumerable<T> 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<T[]> Combinations<T>(IEnumerable<T> 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<T> InsertOf<T>(this IEnumerable<T> self, int index, T item)
{
if (self is null) return null;
switch (self)
{
case List<T> list:
list.Insert(index, item);
break;
default:
var _list = self.ToList();
_list.Insert(index, item);
return _list;
}
return self;
}
public static bool TryGetSingle<T>(this IEnumerable<T> self, out T value)
{
value = default;
if (self.Any())
{
value = self.ElementAt(0);
}
return value is not null;
}
/// <summary>
/// 组合集合中的所有元素
/// </summary>
/// <param name="self"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IEnumerable<T> AllCombinations<T>(this IEnumerable<T> 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<T> SelectManyPro<T>(this IEnumerable<T> self, Func<T, IEnumerable<T>> factory)
{
return Get(self);
IEnumerable<T> Get(IEnumerable<T> list)
{
var newList = new List<T>();
foreach (var x in list)
{
newList.Add(x);
newList.AddRange(Get(factory.Invoke(x)));
}
return newList.Distinct();
}
}
/// <summary>
/// 获取集合中所有的组合,每个组合中的元素个数为输入集合的元素个数,每个元素只出现一次
/// </summary>
/// <param name="self"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IEnumerable<IEnumerable<T>> GetAllCombination<T>(this IEnumerable<T> 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<T> { item, list[j] };
}
}
}
/// <summary>
/// Linq Distinct扩展方法,可以传入自定义比较器
/// </summary>
/// <param name="source"></param>
/// <param name="comparer"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IEnumerable<T> Distinct<T>(
this IEnumerable<T> source, Func<T, T, bool> comparer)
where T : class
=> source.Distinct(new DynamicEqualityComparer<T>(comparer));
/// <summary>
/// 动态自定义比较器
/// </summary>
/// <typeparam name="T"></typeparam>
private sealed class DynamicEqualityComparer<T> : IEqualityComparer<T>
where T : class
{
private readonly Func<T, T, bool> _func;
public DynamicEqualityComparer(Func<T, T, bool> func)
{
_func = func;
}
public bool Equals(T x, T y) => _func(x, y);
public int GetHashCode(T obj) => 0;
}
}
}