一个泛型的ArrayHelper脚本

前言

该脚本包含功能:

  • 查找单个对象(冒泡型查找, 二分法查找【升序, 降序】)
  • 查找满足条件的所有对象 + 两个最值
  • 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);
}

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值