Files
KinginfoGateway/src/Foundation/ThingsGateway.Foundation/Extensions/GenericExtensions.cs

245 lines
8.3 KiB
C#
Raw Normal View History

2024-10-14 19:06:09 +08:00
// ------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://thingsgateway.cn/
// QQ群605534569
// ------------------------------------------------------------------------------
namespace ThingsGateway.Foundation.Extension.Generic;
/// <inheritdoc/>
public static class GenericExtensions
{
/// <summary>
/// 将一个数组进行扩充到指定长度,或是缩短到指定长度<br />
/// </summary>
public static T[] ArrayExpandToLength<T>(this T[] data, int length)
{
if (data == null)
{
return new T[length];
}
if (data.Length == length)
{
return data;
}
Array.Resize(ref data, length);
return data;
}
/// <summary>
/// 将一个数组进行扩充到偶数长度<br />
/// </summary>
public static T[] ArrayExpandToLengthEven<T>(this T[] data)
{
if (data == null)
{
return Array.Empty<T>();
}
return data.Length % 2 == 1 ? data.ArrayExpandToLength(data.Length + 1) : data;
}
/// <summary>
/// <inheritdoc cref="ArrayRemoveDouble{T}(T[], int, int)"/>
/// </summary>
public static T[] ArrayRemoveBegin<T>(T[] value, int length) => ArrayRemoveDouble(value, length, 0);
/// <summary>
/// 从数组中移除指定数量的元素,并返回新的数组
/// </summary>
/// <typeparam name="T">数组元素类型</typeparam>
/// <param name="value">要移除元素的数组</param>
/// <param name="leftLength">从左侧移除的元素个数</param>
/// <param name="rightLength">从右侧移除的元素个数</param>
/// <returns>移除元素后的新数组</returns>
public static T[] ArrayRemoveDouble<T>(T[] value, int leftLength, int rightLength)
{
// 如果输入数组为空或者剩余长度不足以移除左右两侧指定的元素,则返回空数组
if (value == null || value.Length <= leftLength + rightLength)
{
return Array.Empty<T>();
}
// 计算新数组的长度
int newLength = value.Length - leftLength - rightLength;
// 创建新数组
T[] result = new T[newLength];
// 将剩余的元素复制到新数组中
Array.Copy(value, leftLength, result, 0, newLength);
return result;
}
/// <summary>
/// 将指定的数据按照指定长度进行分割
/// </summary>
public static List<T[]> ArraySplitByLength<T>(this T[] array, int length)
{
if (array == null || array.Length == 0)
{
return new List<T[]>();
}
int arrayLength = array.Length;
int numArrays = (arrayLength + length - 1) / length; // 计算所需的数组数量
List<T[]> objArrayList = new List<T[]>(numArrays);
for (int i = 0; i < arrayLength; i += length)
{
int remainingLength = Math.Min(arrayLength - i, length);
T[] destinationArray = new T[remainingLength];
Array.Copy(array, i, destinationArray, 0, remainingLength);
objArrayList.Add(destinationArray);
}
return objArrayList;
}
/// <summary>
/// 将项目列表分解为特定大小的块
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source">原数组</param>
/// <param name="chunkSize">分组大小</param>
/// <param name="isToList">是否ToList</param>
/// <returns></returns>
public static IEnumerable<IEnumerable<T>> ChunkBetter<T>(this IEnumerable<T> source, int chunkSize, bool isToList = false)
{
if (chunkSize <= 0)
chunkSize = source.Count();
var pos = 0;
while (source.Skip(pos).Any())
{
var chunk = source.Skip(pos).Take(chunkSize);
yield return isToList ? chunk.ToList() : chunk;
pos += chunkSize;
}
}
/// <summary>拷贝当前的实例数组,是基于引用层的浅拷贝,如果类型为值类型,那就是深度拷贝,如果类型为引用类型,就是浅拷贝</summary>
public static T[] CopyArray<T>(this T[] value)
{
if (value == null)
{
return Array.Empty<T>();
}
T[] destinationArray = new T[value.Length];
Array.Copy(value, destinationArray, value.Length);
return destinationArray;
}
/// <summary>将一个一维数组中的所有数据按照行列信息拷贝到二维数组里,返回当前的二维数组</summary>
public static T[,] CreateTwoArrayFromOneArray<T>(this T[] array, int row, int col)
{
T[,] arrayFromOneArray = new T[row, col];
int index = 0;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
arrayFromOneArray[i, j] = array[index++];
if (index >= array.Length) return arrayFromOneArray; // 防止数组越界
}
}
return arrayFromOneArray;
}
/// <summary>
/// 将一个数组的前后移除指定位数,返回新的一个数组<br />
/// </summary>
public static T[] RemoveArray<T>(this T[] value, int leftLength, int rightLength)
{
if (value == null || value.Length == 0)
{
return Array.Empty<T>();
}
int newLength = value.Length - leftLength - rightLength;
if (newLength <= 0)
{
return Array.Empty<T>();
}
T[] result = new T[newLength];
Array.Copy(value, leftLength, result, 0, newLength);
return result;
}
/// <summary>
/// 将一个数组的前面指定位数移除,返回新的一个数组<br />
/// </summary>
public static T[] RemoveBegin<T>(this T[] value, int length) => value.RemoveArray(length, 0);
/// <summary>
/// 将一个数组的后面指定位数移除,返回新的一个数组<br />
/// </summary>
public static T[] RemoveLast<T>(this T[] value, int length) => value.RemoveArray(0, length);
/// <summary>
/// 选择数组中的最后几个元素组成新的数组
/// </summary>
/// <typeparam name="T">数组元素类型</typeparam>
/// <param name="value">输入数组</param>
/// <param name="length">选择的元素个数</param>
/// <returns>由最后几个元素组成的新数组</returns>
public static T[] SelectLast<T>(this T[] value, int length)
{
// 如果输入数组为空,则返回空数组
if (value == null || value.Length == 0)
{
return Array.Empty<T>();
}
// 计算实际需要复制的元素个数,取输入数组长度和指定长度的较小值
int count = Math.Min(value.Length, length);
// 创建新数组来存储选择的元素
T[] result = new T[count];
// 复制最后几个元素到新数组中
Array.Copy(value, value.Length - count, result, 0, count);
return result;
}
/// <summary>
/// 从数组中获取指定索引开始的中间一段长度的子数组
/// </summary>
/// <typeparam name="T">数组元素类型</typeparam>
/// <param name="value">输入数组</param>
/// <param name="index">起始索引</param>
/// <param name="length">选择的元素个数</param>
/// <returns>中间指定长度的子数组</returns>
public static T[] SelectMiddle<T>(this T[] value, int index, int length)
{
// 如果输入数组为空,则返回空数组
if (value == null || value.Length == 0)
{
return Array.Empty<T>();
}
// 计算实际需要复制的元素个数,取输入数组剩余元素和指定长度的较小值
int count = Math.Min(value.Length - index, length);
// 创建新数组来存储选择的元素
T[] result = new T[count];
// 复制中间指定长度的元素到新数组中
Array.Copy(value, index, result, 0, count);
return result;
}
}