Files
LL-28/tongxin/NetWorkHelper/Helper/CollectionHelper.cs
moxiliang 7065cad6d7 251024
2025-10-24 14:08:41 +08:00

260 lines
7.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using NetWorkHelper.ICollections;
using System;
using System.Collections.Generic;
namespace NetWorkHelper.Helper
{
public static class CollectionHelper
{
#region Find
/// <summary>
/// Find 从集合中选取符合条件的元素
/// </summary>
public static List<TObject> Find<TObject>(IEnumerable<TObject> source, Predicate<TObject> predicate)
{
List<TObject> list = new List<TObject>();
CollectionHelper.ActionOnSpecification(source, delegate (TObject ele) { list.Add(ele); }, predicate);
return list;
}
#endregion
#region FindFirstSpecification
/// <summary>
/// FindFirstSpecification 返回符合条件的第一个元素
/// </summary>
public static TObject FindFirstSpecification<TObject>(IEnumerable<TObject> source, Predicate<TObject> predicate)
{
foreach (TObject element in source)
{
if (predicate(element))
{
return element;
}
}
return default(TObject);
}
#endregion
#region ContainsSpecification
/// <summary>
/// ContainsSpecification 集合中是否包含满足predicate条件的元素。
/// </summary>
public static bool ContainsSpecification<TObject>(IEnumerable<TObject> source, Predicate<TObject> predicate, out TObject specification)
{
specification = default(TObject);
foreach (TObject element in source)
{
if (predicate(element))
{
specification = element;
return true;
}
}
return false;
}
/// <summary>
/// ContainsSpecification 集合中是否包含满足predicate条件的元素。
/// </summary>
public static bool ContainsSpecification<TObject>(IEnumerable<TObject> source, Predicate<TObject> predicate)
{
TObject specification;
return CollectionHelper.ContainsSpecification<TObject>(source, predicate, out specification);
}
#endregion
#region ActionOnSpecification
/// <summary>
/// ActionOnSpecification 对集合中满足predicate条件的元素执行action。如果没有条件predicate传入null。
/// </summary>
public static void ActionOnSpecification<TObject>(IEnumerable<TObject> collection, Action<TObject> action, Predicate<TObject> predicate)
{
if (collection == null)
{
return;
}
if (predicate == null)
{
foreach (TObject obj in collection)
{
action(obj);
}
return;
}
foreach (TObject obj in collection)
{
if (predicate(obj))
{
action(obj);
}
}
}
#endregion
#region ActionOnEach
/// <summary>
/// ActionOnEach 对集合中的每个元素执行action。
/// </summary>
public static void ActionOnEach<TObject>(IEnumerable<TObject> collection, Action<TObject> action)
{
CollectionHelper.ActionOnSpecification<TObject>(collection, action, null);
}
#endregion
#region GetPart
public static T[] GetPart<T>(T[] ary, int startIndex, int count)
{
return CollectionHelper.GetPart<T>(ary, startIndex, count, false);
}
public static T[] GetPart<T>(T[] ary, int startIndex, int count, bool reverse)
{
if (startIndex >= ary.Length)
{
return null;
}
if (ary.Length < startIndex + count)
{
count = ary.Length - startIndex;
}
T[] result = new T[count];
if (!reverse)
{
for (int i = 0; i < count; i++)
{
result[i] = ary[startIndex + i];
}
}
else
{
for (int i = 0; i < count; i++)
{
result[i] = ary[ary.Length - startIndex - 1 - i];
}
}
return result;
}
#endregion
#region BinarySearch
/// <summary>
/// BinarySearch 从已排序的列表中,采用二分查找找到目标在列表中的位置。
/// 如果刚好有个元素与目标相等则返回true且minIndex会被赋予该元素的位置否则返回false且minIndex会被赋予比目标小且最接近目标的元素的位置
/// </summary>
public static bool BinarySearch<T>(IList<T> sortedList, T target, out int minIndex) where T : IComparable
{
if (target.CompareTo(sortedList[0]) == 0)
{
minIndex = 0;
return true;
}
if (target.CompareTo(sortedList[0]) < 0)
{
minIndex = -1;
return false;
}
if (target.CompareTo(sortedList[sortedList.Count - 1]) == 0)
{
minIndex = sortedList.Count - 1;
return true;
}
if (target.CompareTo(sortedList[sortedList.Count - 1]) > 0)
{
minIndex = sortedList.Count - 1;
return false;
}
int targetPosIndex = -1;
int left = 0;
int right = sortedList.Count - 1;
while (right - left > 1)
{
int middle = (left + right) / 2;
if (target.CompareTo(sortedList[middle]) == 0)
{
minIndex = middle;
return true;
}
if (target.CompareTo(sortedList[middle]) < 0)
{
right = middle;
}
else
{
left = middle;
}
}
minIndex = left;
return false;
}
#endregion
#region GetIntersection GetUnion
/// <summary>
/// GetIntersection 高效地求两个List元素的交集。
/// </summary>
public static List<T> GetIntersection<T>(List<T> list1, List<T> list2) where T : IComparable
{
List<T> largList = list1.Count > list2.Count ? list1 : list2;
List<T> smallList = largList == list1 ? list2 : list1;
largList.Sort();
int minIndex = 0;
List<T> result = new List<T>();
foreach (T tmp in smallList)
{
if (CollectionHelper.BinarySearch<T>(largList, tmp, out minIndex))
{
result.Add(tmp);
}
}
return result;
}
/// <summary>
/// GetUnion 高效地求两个List元素的并集。
/// </summary>
public static List<T> GetUnion<T>(List<T> list1, List<T> list2)
{
SortedDictionary<T, int> result = new SortedDictionary<T, int>();
foreach (T tmp in list1)
{
if (!result.ContainsKey(tmp))
{
result.Add(tmp, 0);
}
}
foreach (T tmp in list2)
{
if (!result.ContainsKey(tmp))
{
result.Add(tmp, 0);
}
}
return (List<T>)CollectionConverter.CopyAllToList<T>(result.Keys);
}
#endregion
}
}