|
|
@@ -1,142 +1,147 @@
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
+using System.Linq;
|
|
|
|
|
|
namespace MeloongCore.Extensions {
|
|
|
public static class EnumerableExtensions {
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// 去重。
|
|
|
- /// </summary>
|
|
|
- public static List<T> Distinct<T>(this IList<T> Arr, Func<T, T, bool> IsEqual) {
|
|
|
- var ResultArray = new List<T>();
|
|
|
- for (int i = 0; i <= Arr.Count - 1; i++) {
|
|
|
- for (int ii = i + 1; ii <= Arr.Count - 1; ii++) {
|
|
|
- if (IsEqual(Arr[i], Arr[ii])) { goto NextElement; }
|
|
|
- }
|
|
|
- ResultArray.Add(Arr[i]);
|
|
|
-NextElement:;
|
|
|
- }
|
|
|
- return ResultArray;
|
|
|
- }
|
|
|
+ #region 去重
|
|
|
|
|
|
/// <summary>
|
|
|
- /// 判断这是否是仅有一个元素的集合。
|
|
|
+ /// 通过比较器进行去重。
|
|
|
+ /// 该方法的效率较低,建议仅在小型列表上使用,或换用 DistinctBy。
|
|
|
/// </summary>
|
|
|
- public static bool IsSingle<T>(this IEnumerable<T> Source) {
|
|
|
- if (Source == null) {
|
|
|
- return false;
|
|
|
- } else if (Source is IList<T> list) {
|
|
|
- return list.Count == 1;
|
|
|
- } else {
|
|
|
- using (var Enumerator = Source.GetEnumerator()) {
|
|
|
- if (!Enumerator.MoveNext()) { return false; }
|
|
|
- if (Enumerator.MoveNext()) { return false; }
|
|
|
- return true;
|
|
|
- }
|
|
|
+ public static IEnumerable<T> Distinct<T>(this IList<T> list, Func<T, T, bool> comparer) {
|
|
|
+ for (int i = 0; i < list.Count; i++) {
|
|
|
+ if (!list.Skip(i + 1).Any(item => comparer(list[i], item))) yield return list[i];
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
/// <summary>
|
|
|
- /// 对集合的每个元素执行指定操作。
|
|
|
+ /// 按对象的指定值去重。
|
|
|
/// </summary>
|
|
|
- public static IEnumerable<T> ForEach<T>(this IEnumerable<T> Collection, Action<T> Action) {
|
|
|
- foreach (T Item in Collection) {
|
|
|
- Action(Item);
|
|
|
+ public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> source, Func<T, TKey> selector) {
|
|
|
+ var seen = new HashSet<TKey>();
|
|
|
+ foreach (var element in source) {
|
|
|
+ if (seen.Add(selector(element))) yield return element;
|
|
|
}
|
|
|
- return Collection;
|
|
|
}
|
|
|
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ #region 取最大、最小值
|
|
|
+
|
|
|
/// <summary>
|
|
|
/// 选择所有最大值对应的对象。
|
|
|
/// 若没有元素则返回空列表。
|
|
|
/// </summary>
|
|
|
- public static List<T> MaxByAll<T, C>(this IEnumerable<T> Source, Func<T, C> Selector) where C : IComparable<C> {
|
|
|
- var Results = new List<T>();
|
|
|
- using (var Enumerator = Source.GetEnumerator()) {
|
|
|
- if (!Enumerator.MoveNext()) { return Results; }
|
|
|
- T MaxItem = Enumerator.Current;
|
|
|
- C MaxValue = Selector(MaxItem);
|
|
|
- Results.Add(MaxItem);
|
|
|
- while (Enumerator.MoveNext()) {
|
|
|
- T CurrentItem = Enumerator.Current;
|
|
|
- C CurrentValue = Selector(CurrentItem);
|
|
|
- int Comparison = CurrentValue.CompareTo(MaxValue);
|
|
|
- if (Comparison > 0) {
|
|
|
- MaxValue = CurrentValue;
|
|
|
- Results.Clear();
|
|
|
- Results.Add(CurrentItem);
|
|
|
- } else if (Comparison == 0) {
|
|
|
- Results.Add(CurrentItem);
|
|
|
+ public static List<T> MaxByAll<T, C>(this IEnumerable<T> source, Func<T, C> selector) where C : IComparable<C> {
|
|
|
+ var results = new List<T>();
|
|
|
+ using (var enumerator = source.GetEnumerator()) {
|
|
|
+ if (!enumerator.MoveNext()) return results;
|
|
|
+ T maxItem = enumerator.Current;
|
|
|
+ C maxValue = selector(maxItem);
|
|
|
+ results.Add(maxItem);
|
|
|
+ while (enumerator.MoveNext()) {
|
|
|
+ T currentItem = enumerator.Current;
|
|
|
+ C currentValue = selector(currentItem);
|
|
|
+ int comparisonResult = currentValue.CompareTo(maxValue);
|
|
|
+ if (comparisonResult > 0) {
|
|
|
+ maxValue = currentValue;
|
|
|
+ results.Clear();
|
|
|
+ results.Add(currentItem);
|
|
|
+ } else if (comparisonResult == 0) {
|
|
|
+ results.Add(currentItem);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- return Results;
|
|
|
+ return results;
|
|
|
}
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// 选择所有最小值对应的对象。
|
|
|
/// 若没有元素则返回空列表。
|
|
|
/// </summary>
|
|
|
- public static List<T> MinByAll<T, C>(this IEnumerable<T> List, Func<T, C> Selector) where C : IComparable<C> {
|
|
|
- var Results = new List<T>();
|
|
|
- using (var Enumerator = List.GetEnumerator()) {
|
|
|
- if (!Enumerator.MoveNext()) { return Results; }
|
|
|
- T MinItem = Enumerator.Current;
|
|
|
- C MinValue = Selector(MinItem);
|
|
|
- Results.Add(MinItem);
|
|
|
- while (Enumerator.MoveNext()) {
|
|
|
- T CurrentItem = Enumerator.Current;
|
|
|
- C CurrentValue = Selector(CurrentItem);
|
|
|
- int Comparison = CurrentValue.CompareTo(MinValue);
|
|
|
- if (Comparison < 0) {
|
|
|
- MinValue = CurrentValue;
|
|
|
- Results.Clear();
|
|
|
- Results.Add(CurrentItem);
|
|
|
- } else if (Comparison == 0) {
|
|
|
- Results.Add(CurrentItem);
|
|
|
+ public static List<T> MinByAll<T, C>(this IEnumerable<T> source, Func<T, C> selector) where C : IComparable<C> {
|
|
|
+ var results = new List<T>();
|
|
|
+ using (var enumerator = source.GetEnumerator()) {
|
|
|
+ if (!enumerator.MoveNext()) return results;
|
|
|
+ T minItem = enumerator.Current;
|
|
|
+ C minValue = selector(minItem);
|
|
|
+ results.Add(minItem);
|
|
|
+ while (enumerator.MoveNext()) {
|
|
|
+ T currentItem = enumerator.Current;
|
|
|
+ C currentValue = selector(currentItem);
|
|
|
+ int comparisonResult = currentValue.CompareTo(minValue);
|
|
|
+ if (comparisonResult < 0) {
|
|
|
+ minValue = currentValue;
|
|
|
+ results.Clear();
|
|
|
+ results.Add(currentItem);
|
|
|
+ } else if (comparisonResult == 0) {
|
|
|
+ results.Add(currentItem);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- return Results;
|
|
|
+ return results;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 选择最大值对应的对象。
|
|
|
/// 若没有元素则返回 Nothing。
|
|
|
/// </summary>
|
|
|
- public static T MaxBy<T, C>(this IEnumerable<T> Source, Func<T, C> Selector) where C : IComparable<C> {
|
|
|
- using (var Enumerator = Source.GetEnumerator()) {
|
|
|
- if (!Enumerator.MoveNext()) { return default(T); }
|
|
|
- T MaxItem = Enumerator.Current;
|
|
|
- C MaxValue = Selector(MaxItem);
|
|
|
- while (Enumerator.MoveNext()) {
|
|
|
- C Value = Selector(Enumerator.Current);
|
|
|
- if (Value.CompareTo(MaxValue) <= 0) { continue; }
|
|
|
- MaxItem = Enumerator.Current;
|
|
|
- MaxValue = Value;
|
|
|
+ public static T MaxBy<T, C>(this IEnumerable<T> source, Func<T, C> selector) where C : IComparable<C> {
|
|
|
+ using (var enumerator = source.GetEnumerator()) {
|
|
|
+ if (!enumerator.MoveNext()) return default;
|
|
|
+ T maxItem = enumerator.Current;
|
|
|
+ C maxValue = selector(maxItem);
|
|
|
+ while (enumerator.MoveNext()) {
|
|
|
+ C value = selector(enumerator.Current);
|
|
|
+ if (value.CompareTo(maxValue) <= 0) continue;
|
|
|
+ maxItem = enumerator.Current;
|
|
|
+ maxValue = value;
|
|
|
}
|
|
|
- return MaxItem;
|
|
|
+ return maxItem;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// 选择最小值对应的对象。
|
|
|
/// 若没有元素则返回 Nothing。
|
|
|
/// </summary>
|
|
|
public static T MinBy<T, C>(this IEnumerable<T> List, Func<T, C> Selector) where C : IComparable<C> {
|
|
|
- using (var Enumerator = List.GetEnumerator()) {
|
|
|
- if (!Enumerator.MoveNext()) { return default; }
|
|
|
- T MinItem = Enumerator.Current;
|
|
|
- C MinValue = Selector(MinItem);
|
|
|
- while (Enumerator.MoveNext()) {
|
|
|
- C Value = Selector(Enumerator.Current);
|
|
|
- if (Value.CompareTo(MinValue) >= 0) { continue; }
|
|
|
- MinItem = Enumerator.Current;
|
|
|
- MinValue = Value;
|
|
|
+ using (var enumerator = List.GetEnumerator()) {
|
|
|
+ if (!enumerator.MoveNext()) { return default; }
|
|
|
+ T minItem = enumerator.Current;
|
|
|
+ C minValue = Selector(minItem);
|
|
|
+ while (enumerator.MoveNext()) {
|
|
|
+ C value = Selector(enumerator.Current);
|
|
|
+ if (value.CompareTo(minValue) >= 0) { continue; }
|
|
|
+ minItem = enumerator.Current;
|
|
|
+ minValue = value;
|
|
|
}
|
|
|
- return MinItem;
|
|
|
+ return minItem;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ #endregion
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 判断集合是否有且仅有一个元素。
|
|
|
+ /// </summary>
|
|
|
+ public static bool IsSingle<T>(this IEnumerable<T> source) {
|
|
|
+ if (source == null) return false;
|
|
|
+ if (source is IList<T> list) return list.Count == 1;
|
|
|
+ using (var enumerator = source.GetEnumerator()) {
|
|
|
+ if (!enumerator.MoveNext()) return false;
|
|
|
+ if (enumerator.MoveNext()) return false;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 对集合的每个元素执行指定操作。
|
|
|
+ /// </summary>
|
|
|
+ public static IEnumerable<T> ForEach<T>(this IEnumerable<T> source, Action<T> action) {
|
|
|
+ foreach (T item in source) action(item);
|
|
|
+ return source;
|
|
|
+ }
|
|
|
+
|
|
|
}
|
|
|
}
|