前言
该脚本包含功能:
- 查找单个对象(冒泡型查找, 二分法查找【升序, 降序】)
- 查找满足条件的所有对象 + 两个最值
- 5种排序方法 【升序,降序】
- 仅对数组最后一个进行排序
- 对数组内所有元素进行 洗牌 筛选
代码部分
using System;
using System.Collections.Generic;
using System.Diagnostics;
/****************************************************
文件:ArrayHelper.cs
作者:GTY
日期:#CreateTime#
功能:
查找单个对象(冒泡型查找, 二分法查找【升序, 降序】)
查找满足条件的所有对象 + 两个最值
5种排序方法 【升序,降序】
仅对数组最后一个进行排序
对数组内所有元素进行 洗牌 筛选
*****************************************************/
namespace Tool.Common
{
/*C#的拓展方法
*
* 三要素:
* 1.拓展方法所在类必须是静态类
* 2.在第一个参数上, 使用this关键字修饰被拓展类型
* 3.在另一个命名空间下
*
* 作用: 方便调用
*
* 语法: 被拓展类型.方法名
*/
/// <summary>
/// 数组助手类, 对数组的改造与操作
/// 提供一些数组常用功能
/// </summary>
public static class ArrayHelper
{
// 查找单个对象(冒泡型查找, 二分法查找【升序, 降序】)
// 查找满足条件的所有对象 + 两个最值
// 5种排序方法 【升序,降序】
// 仅对数组最后一个进行排序
// 对数组内所有元素进行 洗牌 筛选
/// <summary>
/// 排序类型
/// </summary>
public enum SortType
{
Bubble, // 冒泡排序 o(n^2)
Quick, // 快速排序 o(nlogn) / o(n^2)
Merge, // 归并排序 时间复杂度: o(nlogn) 空间复杂度: o(n)
Heap, // 堆排序 o(nlogn) + o(n)(建堆)
Last, // 仅对数组最后一个进行排序
Shell, // 希尔排序 o(n < x < n^2)
}
/// <summary>
/// 查找类型
/// </summary>
public enum SearchType
{
Bubble, // 冒泡查找
Binary, // 二分法查找
}
#region 查找方法
/// <summary>
/// 查找满足条件的单个元素
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <param name="array">数组</param>
/// <param name="condition">查找条件</param>
/// <returns></returns>
public static T Search<T>
(this T[] array, Func<T, bool> condition)
{
for (int i = 0; i < array.Length; i++)
{
// 满足条件
if (condition(array[i]))
return array[i];
}
// 泛型的默认值
return default(T);
}
/// <summary>
/// 查找满足条件的所有元素
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <param name="array">数组</param>
/// <param name="condition">查找条件</param>
/// <returns></returns>
public static T[] FindAll<T>
(this T[] array, Func<T, bool> condition)
{
// 集合存储满足条件的元素
List<T> list = new List<T>();
for (int i = 0; i < array.Length; i++)
{
// 查找条件
if (condition(array[i]))
list.Add(array[i]);
}
return list.ToArray();
}
/// <summary>
/// 查找 在升序列表中查找
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">查找类型</typeparam>
/// <param name="array">查找的数组</param>
/// <param name="searchType">查找的方式</param>
/// <param name="key">查找的值</param>
/// <param name="condition">查找条件(通过谁进行查找例如id)</param>
/// <returns></returns>
public static T SearchAscending<T, Q>
(this T[] array, SearchType searchType, Q key, Func<T, Q> condition) where Q : IComparable
{
switch (searchType)
{
case SearchType.Bubble:
UnityEngine.Debug.LogError("此函数不含有冒泡查找! 请使用 Search");
break;
case SearchType.Binary:
return array.BinaryAscendingSearch(key, condition);
}
return default(T);
}
/// <summary>
/// 查找 在降序列表中查找
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">查找类型</typeparam>
/// <param name="array">查找的数组</param>
/// <param name="searchType">查找的方式</param>
/// <param name="key">查找的值</param>
/// <param name="condition">查找条件(通过谁进行查找例如id)</param>
/// <returns></returns>
public static T SearchDescending<T, Q>
(this T[] array, SearchType searchType, Q key, Func<T, Q> condition) where Q : IComparable
{
switch (searchType)
{
case SearchType.Bubble:
UnityEngine.Debug.LogError("此函数不含有冒泡查找! 请使用 Search");
break;
case SearchType.Binary:
return array.BinaryDescendingSearch(key, condition);
}
return default(T);
}
/// <summary>
/// 二分查找 升序列表
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <param name="array">数组</param>
/// <param name="condition">查找条件</param>
/// <returns></returns>
static T BinaryAscendingSearch<T, Q>
(this T[] array, Q key, Func<T, Q> condition) where Q : IComparable
{
int left = 0;
int right = array.Length - 1;
int mid;
while (left <= right) // 候选区有值
{
mid = (left + right) / 2;
if (condition(array[mid]).CompareTo(key) == 0)
return array[mid];
else if (condition(array[mid]).CompareTo(key) > 0)
right = mid - 1;
else
left = mid + 1;
}
return default(T);
}
/// <summary>
/// 二分查找 降序列表
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <param name="array">数组</param>
/// <param name="condition">查找条件</param>
/// <returns></returns>
static T BinaryDescendingSearch<T, Q>
(this T[] array, Q key, Func<T, Q> condition) where Q : IComparable
{
int left = 0;
int right = array.Length - 1;
int mid;
while (left <= right) // 候选区有值
{
mid = (left + right) / 2;
if (condition(array[mid]).CompareTo(key) == 0)
return array[mid];
else if (condition(array[mid]).CompareTo(key) < 0)
right = mid - 1;
else
left = mid + 1;
}
return default(T);
}
#endregion
/// <summary>
/// 最大值
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">比较条件的返回值类型</typeparam>
/// <param name="array">要比较的数组</param>
/// <param name="condition">比较的方法</param>
/// <returns></returns>
public static T GetMax<T, Q>
(this T[] array, Func<T, Q> condition) where Q : IComparable
{
T max = array[0];
for (int i = 0; i < array.Length; i++)
{
// 比较条件
// 拿max 与 数组元素进行比较
if (condition(max).
CompareTo
(condition(array[i])) < 0)
{
max = array[i];
}
}
return max;
}
/// <summary>
/// 最小值
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">比较条件的返回值类型</typeparam>
/// <param name="array">要比较的数组</param>
/// <param name="condition">比较的方法</param>
/// <returns></returns>
public static T GetMin<T, Q>
(this T[] array, Func<T, Q> condition) where Q : IComparable
{
T max = array[0];
for (int i = 0; i < array.Length; i++)
{
// 比较条件
// 拿max 与 数组元素进行比较
if (condition(max).
CompareTo
(condition(array[i])) > 0)
{
max = array[i];
}
}
return max;
}
#region 排序方法
/// <summary>
/// 顺序升序策略
/// 特别大的数组时才推荐使用堆排序
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">比较条件的返回值类型</typeparam>
/// <param name="array">要比较的数组</param>
/// <param name="sortType">排序类型</param>
/// <param name="condition">比较的委托方法</param>
/// <returns></returns>
public static T[] OrderAscending<T, Q>
(this T[] array, SortType sortType, Func<T, Q> condition) where Q : IComparable
{
switch (sortType)
{
case SortType.Bubble:
return array.BubbleOrderAscending(condition);
case SortType.Quick:
array.QuickOrderAscending(0, array.Length - 1, condition);
return array;
case SortType.Merge:
return array.MergeOrderAscending(0, array.Length - 1, condition);
case SortType.Heap:
return array.HeapOrderAscending(condition);
case SortType.Last:
return array.InsertLastAscending(condition);
case SortType.Shell:
return array.ShellAscending(condition);
}
return null;
}
/// <summary>
/// 顺序降序策略
/// 特别大的数组时才推荐使用堆排序
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">比较条件的返回值类型</typeparam>
/// <param name="array">要比较的数组</param>
/// <param name="condition">比较的方法</param>
/// <returns></returns>
public static T[] OrderDescending<T, Q>
(this T[] array, SortType sortType, Func<T, Q> condition) where Q : IComparable
{
switch (sortType)
{
case SortType.Bubble:
return array.BubbleOrderDescending(condition);
case SortType.Quick:
array.QuickOrderDescending(0, array.Length - 1, condition);
return array;
case SortType.Merge:
return array.MergeOrderDescending(0, array.Length - 1, condition);
case SortType.Heap:
return array.HeapOrderDescending(condition);
case SortType.Last:
return array.InsertLastDescending(condition);
case SortType.Shell:
return array.ShellDescending(condition);
}
return null;
}
#region 排序具体方法
#region 冒泡排序
/// <summary>
/// 冒泡升序 o(n^2)
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">条件的返回值类型</typeparam>
/// <param name="array">需要排序的数组</param>
/// <param name="condition">排序条件(通过谁进行排序例如id)</param>
/// <returns></returns>
static T[] BubbleOrderAscending<T, Q>
(this T[] array, Func<T, Q> condition) where Q : IComparable
{
for (int i = 0; i < array.Length - 1; i++)
{
for (int j = 0; j < array.Length - 1 - i; j++)
{
//if (array[j] > array[j+1])
if (condition(array[j]).CompareTo(condition(array[j + 1])) > 0)
{
T temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
return array;
}
/// <summary>
/// 冒泡降序 o(n^2)
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">条件的返回值类型</typeparam>
/// <param name="array">需要排序的数组</param>
/// <param name="condition">排序条件(通过谁进行排序例如id)</param>
/// <returns></returns>
static T[] BubbleOrderDescending<T, Q>
(this T[] array, Func<T, Q> condition) where Q : IComparable
{
for (int i = 0; i < array.Length - 1; i++)
{
for (int j = 0; j < array.Length - 1 - i; j++)
{
//if (array[j] > array[j+1])
if (condition(array[j]).CompareTo(condition(array[j + 1])) < 0)
{
T temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
return array;
}
#endregion
#region 快排
/// <summary>
/// 快速排序 升序 o(nlogn) 最坏情况 o(n^2)
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">条件的返回值类型</typeparam>
/// <param name="array">需要排序的数组</param>
/// <param name="start">起始元素</param>
/// <param name="end">终止元素</param>
/// <param name="condition">排序条件(通过谁进行排序例如id)</param>
static void QuickOrderAscending<T, Q>
(this T[] array, int start, int end, Func<T, Q> condition) where Q : IComparable
{
if (start >= end) return; // 递归出口
// 假设第一个元素作为基准
T pivot = array[start];
// 升序
// 定义两个指向开头与结尾
int left = start;
int right = end;
// 小的放左边 大的放右边
// 直到两个数相遇结束
// 左边小于右边
while (left < right)
{
// 从右往左查找比pivot大的值
while (left < right && condition(array[right]).CompareTo(condition(pivot)) >= 0)
right--;
// 将大的值放左边
array[left] = array[right];
// 从左往右搜索比pivot小的值
while (left < right && condition(array[left]).CompareTo(condition(pivot)) <= 0)
left++;
// 将小的值放右边
array[right] = array[left];
}
// 此时left = right
array[left] = pivot;
// 递归
array.QuickOrderAscending(start, left - 1, condition);
array.QuickOrderAscending(left + 1, end, condition);
}
/// <summary>
/// 快速排序 降序 o(nlogn) 最坏情况 o(n^2)
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">条件的返回值类型</typeparam>
/// <param name="array">需要排序的数组</param>
/// <param name="start">起始元素</param>
/// <param name="end">终止元素</param>
/// <param name="condition">排序条件(通过谁进行排序例如id)</param>
static void QuickOrderDescending<T, Q>
(this T[] array, int start, int end, Func<T, Q> condition) where Q : IComparable
{
if (start >= end) return; // 递归出口
// 假设第一个元素作为基准
T pivot = array[start];
// 升序
// 定义两个指向开头与结尾
int left = start;
int right = end;
// 大的放左边 小的放右边
// 直到两个数相遇结束
// 左边大于右边
while (left < right)
{
// 从右往左查找比pivot小的值
while (left < right && condition(array[right]).CompareTo(condition(pivot)) <= 0)
right--;
// 将大的值放左边
array[left] = array[right];
// 从左往右搜索比pivot大的值
while (left < right && condition(array[left]).CompareTo(condition(pivot)) >= 0)
left++;
// 将大的值放右边
array[right] = array[left];
}
// 此时left = right
array[left] = pivot;
// 递归
array.QuickOrderDescending(start, left - 1, condition);
array.QuickOrderDescending(left + 1, end, condition);
}
#endregion
#region 归并排序 空间复杂度 o(n)
/// <summary>
/// 归并排序 升序
/// 【时间复杂度: o(nlogn) 空间复杂度: o(n)】
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">条件的返回值类型</typeparam>
/// <param name="array">需要排序的数组</param>
/// <param name="low">起始元素</param>
/// <param name="mid">中间元素</param>
/// <param name="high">终止元素</param>
/// <param name="condition">排序条件(通过谁进行排序例如id)</param>
/// <returns></returns>
static T[] MergeOrderAscending<T, Q>
(this T[] array, int low, int high, Func<T, Q> condition) where Q : IComparable
{
int mid;
if (low < high) // 至少有两个元素 递归
{
mid = (low + high) / 2;
// 将左边排好序
array.MergeOrderAscending(low, mid, condition);
// 将右侧拍好序
array.MergeOrderAscending(mid + 1, high, condition);
// 左右归并
array.MergeAscending(low, mid, high, condition);
}
return array;
}
/// <summary>
/// 归并排序 降序
/// 【时间复杂度: o(nlogn) 空间复杂度: o(n)】
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">条件的返回值类型</typeparam>
/// <param name="array">需要排序的数组</param>
/// <param name="low">起始元素</param>
/// <param name="mid">中间元素</param>
/// <param name="high">终止元素</param>
/// <param name="condition">排序条件(通过谁进行排序例如id)</param>
/// <returns></returns>
static T[] MergeOrderDescending<T, Q>
(this T[] array, int low, int high, Func<T, Q> condition) where Q : IComparable
{
int mid;
if (low < high) // 至少有两个元素 递归
{
mid = (low + high) / 2;
// 将左边排好序
array.MergeOrderDescending(low, mid, condition);
// 将右侧拍好序
array.MergeOrderDescending(mid + 1, high, condition);
// 左右归并
array.MergeDescending(low, mid, high, condition);
}
return array;
}
/// <summary>
/// 归并 升序
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="Q"></typeparam>
/// <param name="array"></param>
/// <param name="low"></param>
/// <param name="mid"></param>
/// <param name="high"></param>
static void MergeAscending<T, Q>
(this T[] array, int low, int mid, int high, Func<T, Q> condition) where Q : IComparable
{
int i = low;
int j = mid + 1;
T[] tmp = new T[high - low + 1];
int k = 0;
while (i <= mid && j <= high) // 只要左右两边都有数
{
if (condition(array[i]).CompareTo(condition(array[j])) < 0)
{
tmp[k] = array[i];
i++;
}
else
{
tmp[k] = array[j];
j++;
}
k++;
}
// 两部分肯定有一部分没数了
while (i <= mid)
{
tmp[k] = array[i];
i++;
k++;
}
while (j <= high)
{
tmp[k] = array[j];
j++;
k++;
}
for (k = 0, i = low; i <= high; k++, i++)
array[i] = tmp[k];
}
/// <summary>
/// 归并 降序
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="Q"></typeparam>
/// <param name="array"></param>
/// <param name="low"></param>
/// <param name="mid"></param>
/// <param name="high"></param>
static void MergeDescending<T, Q>
(this T[] array, int low, int mid, int high, Func<T, Q> condition) where Q : IComparable
{
int i = low;
int j = mid + 1;
T[] tmp = new T[high - low + 1];
int k = 0;
while (i <= mid && j <= high) // 只要左右两边都有数
{
if (condition(array[i]).CompareTo(condition(array[j])) > 0)
{
tmp[k] = array[i];
i++;
}
else
{
tmp[k] = array[j];
j++;
}
k++;
}
// 两部分肯定有一部分没数了
while (i <= mid)
{
tmp[k] = array[i];
i++;
k++;
}
while (j <= high)
{
tmp[k] = array[j];
j++;
k++;
}
for (k = 0, i = low; i <= high; k++, i++)
array[i] = tmp[k];
}
#endregion
#region 堆排序
/// <summary>
/// 堆排序 升序 o(nlogn) 但需要 o(n) 的建堆
/// 推荐在特别大的数组时使用
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">条件的返回值类型</typeparam>
/// <param name="array">需要排序的数组</param>
/// <param name="condition">排序条件(通过谁进行排序例如id)</param>
static T[] HeapOrderAscending<T, Q>
(this T[] array, Func<T, Q> condition) where Q : IComparable
{
int n = array.Length;
// i 标识建堆时调整的部分的根的下标
for (int i = (n - 2) / 2; i > -1; i--)
{
// 由于high 的唯一一个作用就是检测 j(在Sift方法中)是否越界所以使用 末尾编号即可
SiftAscending(array, i, n - 1, condition);
}
// 建堆完成
// 开始排列
// i 一直是堆的最后一个元素
for (int i = n - 1; i > -1; i--)
{
// 做交换
T tmp = array[0];
array[0] = array[i];
array[i] = tmp;
SiftAscending(array, 0, i - 1, condition); // i-1 是新的high
}
// 排序完成!
return array;
}
/// <summary>
/// 堆排序 降序 o(nlogn) 但需要 o(n) 的建堆
/// 推荐在特别大的数组时使用
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">条件的返回值类型</typeparam>
/// <param name="array">需要排序的数组</param>
/// <param name="condition">排序条件(通过谁进行排序例如id)</param>
static T[] HeapOrderDescending<T, Q>
(this T[] array, Func<T, Q> condition) where Q : IComparable
{
int n = array.Length;
// i 标识建堆时调整的部分的根的下标
for (int i = (n - 2) / 2; i > -1; i--)
{
// 由于high 的唯一一个作用就是检测 j(在Sift方法中)是否越界所以使用 末尾编号即可
SiftDescending(array, i, n - 1, condition);
}
// 建堆完成
// 开始排列
// i 一直是堆的最后一个元素
for (int i = n - 1; i > -1; i--)
{
// 做交换
T tmp = array[0];
array[0] = array[i];
array[i] = tmp;
SiftDescending(array, 0, i - 1, condition); // i-1 是新的high
}
// 排序完成!
return array;
}
/// <summary>
/// 将数组调整为二叉树 大根堆 生成升序列表
/// </summary>
/// <param name="array">需要排序的数组</param>
/// <param name="low">堆的节点位置</param>
/// <param name="high">堆的最后一个元素的位置</param>
static void SiftAscending<T, Q>
(this T[] array, int low, int high, Func<T, Q> condition) where Q : IComparable
{
// 调整数组
int i = low;// 最开始指向根节点
int j = 2 * i + 1; // 开始是左节点
T tmp = array[low]; // 把堆顶存起来
while (j <= high) // 只要j位置有数据
{
if ((j + 1) <= high && condition(array[j + 1]).CompareTo(condition(array[j])) > 0) // 右节点存在且比较大
j = j + 1; // 指向右子节点
if (condition(array[j]).CompareTo(condition(tmp)) > 0)
{
array[i] = array[j];
i = j; // 向下一层
j = 2 * i + 1;
}
else // tmp 更大
{
//array[i] = tmp; // 把tmp放到某一级位置上
break;
}
}
array[i] = tmp; // 把tmp放到某一级位置上
}
/// <summary>
/// 将数组调整为二叉树 小根堆 生成降序列表
/// </summary>
/// <param name="list">列表</param>
/// <param name="low">堆的节点位置</param>
/// <param name="high">堆的最后一个元素的位置</param>
static void SiftDescending<T, Q>
(this T[] array, int low, int high, Func<T, Q> condition) where Q : IComparable
{
// 调整数组
int i = low;// 最开始指向根节点
int j = 2 * i + 1; // 开始是左节点
T tmp = array[low]; // 把堆顶存起来
while (j <= high) // 只要j位置有数据
{
if ((j + 1) <= high && condition(array[j + 1]).CompareTo(condition(array[j])) < 0) // 右节点存在且比较小
j = j + 1; // 指向右子节点
if (condition(array[j]).CompareTo(condition(tmp)) < 0)
{
array[i] = array[j];
i = j; // 向下一层
j = 2 * i + 1;
}
else // tmp 更小
{
//array[i] = tmp; // 把tmp放到某一级位置上
break;
}
}
array[i] = tmp; // 把tmp放到某一级位置上
}
#endregion
#region 希尔排序
/// <summary>
/// 希尔升序算法 o(n < x < n^2)
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">条件的返回值类型</typeparam>
/// <param name="array">需要排序的数组</param>
/// <param name="condition">排序条件(通过谁进行排序例如id)</param>
/// <returns></returns>
static T[] ShellAscending<T, Q>
(this T[] array, Func<T, Q> condition) where Q : IComparable
{
for (int gap = array.Length / 2; gap > 0; gap /= 2)
{
for (int i = gap; i < array.Length; i++)
{
int index = i;
T tmp = array[i];
while (index - gap >= 0 && condition(array[index - gap]).CompareTo(condition(tmp)) > 0)
{
array[index] = array[index - gap];
index -= gap;
}
array[index] = tmp;
}
}
return array;
}
/// <summary>
/// 希尔降序算法 o(n < x < n^2)
/// 此选择 gap /= 2;
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">条件的返回值类型</typeparam>
/// <param name="array">需要排序的数组</param>
/// <param name="condition">排序条件(通过谁进行排序例如id)</param>
/// <returns></returns>
static T[] ShellDescending<T, Q>
(this T[] array, Func<T, Q> condition) where Q : IComparable
{
for (int gap = array.Length / 2; gap > 0; gap /= 2)
{
for (int i = gap; i < array.Length; i++)
{
int index = i;
T tmp = array[i];
while (index - gap >= 0 && condition(array[index - gap]).CompareTo(condition(tmp)) < 0)
{
array[index] = array[index - gap];
index -= gap;
}
array[index] = tmp;
}
}
return array;
}
#endregion
#endregion
/// <summary>
/// 对一个升序数组新添加的最后一个位新元素
/// 进行 升序排序
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">条件的返回值类型</typeparam>
/// <param name="array">需要排序的数组</param>
/// <param name="condition">排序条件(通过谁进行排序例如id)</param>
/// <returns></returns>
static T[] InsertLastAscending<T, Q>
(this T[] array, Func<T, Q> condition) where Q : IComparable
{
T insertVal = array[array.Length - 1]; //预备要插入的数
int insertIndex = array.Length - 2; //找出它前一个数的下标(等下 准备插入的数 要跟这个数做比较
//如果这个条件满足,说明还没有找到适当的位置
while (insertIndex >= 0 && condition(insertVal).CompareTo(condition(array[insertIndex])) < 0) //小于是升序,大于是降序
{
array[insertIndex + 1] = array[insertIndex]; //把比插入数大的往后移
insertIndex--; //指针继续往前移
}
//插入(这时候给insertVal找到适当位置)
array[insertIndex + 1] = insertVal;
return array;
}
/// <summary>
/// 对一个降序数组新添加的最后一个位新元素
/// 进行 降序排序
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <typeparam name="Q">条件的返回值类型</typeparam>
/// <param name="array">需要排序的数组</param>
/// <param name="condition">排序条件(通过谁进行排序例如id)</param>
/// <returns></returns>
static T[] InsertLastDescending<T, Q>
(this T[] array, Func<T, Q> condition) where Q : IComparable
{
T insertVal = array[array.Length - 1]; //预备要插入的数
int insertIndex = array.Length - 2; //找出它前一个数的下标(等下 准备插入的数 要跟这个数做比较
//如果这个条件满足,说明还没有找到适当的位置
while (insertIndex >= 0 && condition(insertVal).CompareTo(condition(array[insertIndex])) > 0) //小于是升序,大于是降序
{
array[insertIndex + 1] = array[insertIndex]; //把比插入数大的往后移
insertIndex--; //指针继续往前移
}
//插入(这时候给insertVal找到适当位置)
array[insertIndex + 1] = insertVal;
return array;
}
#endregion
/// <summary>
/// 筛选方法, 不满足条件的位置为 null
/// </summary>
/// <typeparam name="T">被筛选的类型</typeparam>
/// <typeparam name="Q">筛选的类型</typeparam>
/// <param name="array">被筛选的数组</param>
/// <param name="condition">筛选条件</param>
/// <returns></returns>
public static Q[] Select<T, Q>
(this T[] array, Func<T, Q> condition)
{
// 存储筛选出来满足条件的元素
Q[] result = new Q[array.Length];
for (int i = 0; i < array.Length; i++)
{
// 筛选条件【满足筛选条件, 将该元素存到 result 中】
result[i] = condition(array[i]);
}
return result;
}
/// <summary>
/// 对所有位置进行洗牌操作
/// </summary>
/// <typeparam name="T">数组类型</typeparam>
/// <param name="array">洗牌数组</param>
/// <returns></returns>
public static T[] Shuffle<T>
(this T[] array)
{
int randomIndex;
for (int i = 0; i < array.Length - 1; i++)
{
randomIndex = UnityEngine.Random.Range(i, array.Length);
T tmp = array[randomIndex];
array[randomIndex] = array[i];
array[i] = tmp;
}
return array;
}
}
}
使用方法
- 引用命名空间
using Tool.Common;
- 声明查找
public struct TestStruct { public int ID; public string Name; } public class NewBehaviourScript : MonoBehaviour { public TestStruct[] testStrings; private void Start() { // 查找 ID == 0 的元素 TestStruct temp = testStrings.Search((t) => t.ID == 0); } }
案例
下面这个是博主项目中拿来根据权重降序排列的例子
[System.Serializable]
public struct Testimony
{
/// <summary>
/// 内容
/// </summary>
[HideLabel, TextArea(2, 14)]
public string content;
[Tooltip("根据权重进行排序与执行")]
public int weight;
}
public Testimony[] testimonies;
[Button("根据权重对证词进行排序")]
public void OrderDescendingTestimonies()
{
testimonies.OrderDescending(ArrayHelper.SortType.Quick, (t) => t.weight);
}