Files
KinginfoGateway/src/Foundation/ThingsGateway.Foundation/Extensions/GenericExtensions.cs
2024-12-19 11:16:24 +08:00

245 lines
8.3 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.

// ------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人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;
}
}