ArrayUtil.ts 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. export default class ArrayUtil {
  2. /**随机打乱一个数组 */
  3. public static shuffleArray<T>(array: T[]): T[] {
  4. let currentIndex = array.length;
  5. let temporaryValue;
  6. let randomIndex;
  7. // While there remain elements to shuffle...
  8. while (currentIndex !== 0) {
  9. // Pick a remaining element...
  10. randomIndex = Math.floor(Math.random() * currentIndex);
  11. currentIndex--;
  12. // And swap it with the current element.
  13. temporaryValue = array[currentIndex];
  14. array[currentIndex] = array[randomIndex];
  15. array[randomIndex] = temporaryValue;
  16. }
  17. return array;
  18. }
  19. // Fisher-Yates 洗牌算法
  20. //const originalArray = [1, 2, 3, 4, 5];
  21. //const shuffledArray = shuffleArray([...originalArray]);
  22. public static shuffleArray2<T>(array: T[]): T[] {
  23. for (let i = array.length - 1; i > 0; i--) {
  24. // 生成一个随机索引
  25. const j = Math.floor(Math.random() * (i + 1));
  26. // 交换元素
  27. [array[i], array[j]] = [array[j], array[i]];
  28. }
  29. return array;
  30. }
  31. /**合并两个数组元素,移除相同的 */
  32. public static MergeAndRemoveDuplicates<T>(arr1: T[], arr2: T[]): T[] {
  33. const merged = [...arr1, ...arr2]; // 合并两个数组
  34. const uniqueValues = Array.from(new Set(merged)); // 去重
  35. return uniqueValues;
  36. }
  37. /**排除数组1在数组2里有的元素,返回新数组*/
  38. public static ExcludeElements<T>(array1:T[],array2:T[]):T[]{
  39. const set = new Set(array2); // 将 array2 转换为 Set
  40. return array1.filter(item => !set.has(item));
  41. }
  42. /**检测数组元素是否能满足顺序的组合*/
  43. public static checkSequentialCombination(arr: number[]): number[] {
  44. const sortedArr = arr.slice().sort((a, b) => a - b);
  45. for (let i = 0; i < sortedArr.length - 1; i++) {
  46. if (sortedArr[i] + 1 !== sortedArr[i + 1]) {
  47. return [];
  48. }
  49. }
  50. return sortedArr;
  51. }
  52. /**从一个数组中找出是否有连续的组合*/
  53. public static findSequentialCombinations(arr: number[]): number[][] {
  54. const result: number[][] = [];
  55. arr.sort((a, b) => a - b);
  56. let currentSequence: number[] = [];
  57. for (let i = 0; i < arr.length; i++) {
  58. if (currentSequence.length === 0 || arr[i] === currentSequence[currentSequence.length - 1] + 1) {
  59. currentSequence.push(arr[i]);
  60. } else {
  61. if (currentSequence.length > 1) {
  62. result.push(currentSequence);
  63. }
  64. currentSequence = [arr[i]];
  65. }
  66. }
  67. if (currentSequence.length > 1) {
  68. result.push(currentSequence);
  69. }
  70. return result;
  71. }
  72. /*eg:const arr = [2, 4,2, 5, 3, 6, 9,9,10,11,];
  73. const combinations = this.findSequentialCombinations(arr);
  74. if (combinations.length > 0) {
  75. console.log("所有可能的连续顺序组合为:");
  76. combinations.forEach(combination => {
  77. console.log(combination);
  78. });
  79. } else {
  80. console.log("无法找到连续顺序组合");
  81. }*/
  82. /**数组中删除一个合条件的*/
  83. public static DeleteOneItem<T>(list:Array<T>,check:(item:T)=>boolean):T|null{
  84. let length=list.length;
  85. for(let i:number=0;i<length;i++){
  86. if(check(list[i])){
  87. return list.splice(i,1)[0];
  88. //i--;
  89. //length--;
  90. }
  91. }
  92. return null;
  93. }
  94. /**插入排序(适用于差异不会很大,相对有序的数据)Array.sort() 快速排序 算法更适用于混乱无章的数据 */
  95. public static InsertionSort(array:any[]):void{
  96. const count = array.length;
  97. if(count<=1)return;
  98. let t1:any;
  99. let t2:any;
  100. for(let i=1;i<count;i++){
  101. t1 = array[i];
  102. let j:number;
  103. for(j=i;j>0 && t1.sortValue>(t2=array[j-1]).sortValue;j--){
  104. array[j]=t2;
  105. }
  106. array[j]=t1;
  107. }
  108. }
  109. // 元素排序
  110. /*示例
  111. 负数在前
  112. const checkMinusNumber = function (val: number) {
  113. return val > 0;
  114. };
  115. const arr = [2, 4, 5, 6, 7, -8, -10 - 12, -2];
  116. adjustArrayOrder.reorder(arr, checkMinusNumber);
  117. console.log(arr);
  118. */
  119. public static reorder(arr: Array<number>, checkFun: (checkVal: number) => boolean): void {
  120. let end = arr.length - 1;
  121. let begin =0;
  122. while (begin < end) {
  123. // 向后移动begin
  124. while (begin < end && !checkFun(arr[begin])) {
  125. begin++;
  126. }
  127. // 向前移动end
  128. while (begin < end && checkFun(arr[end])) {
  129. end--;
  130. }
  131. // begin与end都指向了正确的位置
  132. if (begin < end) {
  133. // 交换两个元素的顺序
  134. [arr[begin], arr[end]] = [arr[end], arr[begin]];
  135. }
  136. }
  137. }
  138. //冒泡排序
  139. /// <summary>
  140. /// 各种类型冒泡排序比
  141. /// </summary>/// 例子:
  142. /// CommonSort<int>(new int[]{2,3,1,45,123,4},compare)
  143. /// bool compare(int a,int b){
  144. /// if(a>b)return true;
  145. /// reutn false;
  146. /// }
  147. /// <param name="sortArray"></param>
  148. /// <param name="compareMethod"></param>
  149. /// <typeparam name="T"></typeparam>
  150. static CommonSort<T>(sortArray:Array<T>, compareMethod:(a:T,b:T)=>boolean):void
  151. {
  152. let swapped = true;
  153. do
  154. {
  155. swapped = false;
  156. for (let i = 0; i < sortArray.length - 1; i++)
  157. {
  158. if (compareMethod(sortArray[i], sortArray[i + 1]))
  159. {
  160. let temp = sortArray[i];
  161. sortArray[i] = sortArray[i + 1];
  162. sortArray[i + 1] = temp;
  163. swapped = true;
  164. }
  165. }
  166. } while (swapped);
  167. }
  168. /**归并排序 */
  169. /*var arr: number[] = [];
  170. for (var i: number = 0; i < 1000; i++) {
  171. arr.push(Math.floor(1000 - i));//生成降序的数组
  172. }
  173. MergeSort(arr, 0, arr.length);//调用归并排序算法*/
  174. //拆分数组 分
  175. static MergeSort(arr: number[], lo: number, hi: number): void {
  176. if (hi - lo < 2) return;//单个元素无需考虑
  177. var mi: number = (lo + hi) >> 1;//已中点为界 或者改成Math.floor((lo + hi) / 2)
  178. this.MergeSort(arr, lo, mi);//对左边排序
  179. this.MergeSort(arr, mi, hi);//对右边排序
  180. this.merge(arr, lo, mi, hi);//归并
  181. }
  182. //归并算法实现 合
  183. private static merge(arr: number[], lo: number, mi: number, hi: number): void {
  184. var A: number[] = arr.slice(lo, hi);//A[lo, hi)=arr[lo, hi)
  185. var lb: number = mi - lo;
  186. var B: number[] = new Array(lb);
  187. for (var i = 0; i < lb; B[i] = A[i++]);//复制左子向量B[0, lb) = arr[lo, mi)
  188. var lc: number = hi - mi;
  189. var C: number[] = arr.slice(mi, hi);//后子向量C[0,lc) = arr[mi, hi)
  190. for (var i = 0, j = 0, k = 0; j < lb;) {//反复冲B和C中取出更小者
  191. if (k < lc && C[k] < B[j]) {//将其归入A中
  192. A[i++] = C[k++];
  193. }
  194. if (lc <= k || B[j] <= C[k]) {
  195. A[i++] = B[j++];
  196. }
  197. }
  198. for (var i = 0; i < A.length; arr[lo + i] = A[i++]);//把A中的值赋给原来的数组
  199. B.length = 0;
  200. C.length = 0;
  201. A.length = 0;
  202. }
  203. }