using System; using System.Collections.Generic; using System.Numerics; using Unity.VisualScripting; public static class CustomExtension { /// /// insert value to list and sort. /// static public void OrderInsert(this IList arr, T value, Func comparison) { arr.Add(value); for (int i = arr.Count - 1; i > 0; --i) { if (comparison(arr[i - 1], arr[i]) > 0) { T tmp = arr[i]; arr[i] = arr[i - 1]; arr[i - 1] = tmp; } else { break; } } } /// /// sort list. /// static public void InsertionSort(this IList arr, Func comparison) { for (int i = 1; i < arr.Count; ++i) { for (int j = i; j > 0; --j) { if (comparison(arr[j - 1], arr[j]) > 0) { T tmp = arr[j]; arr[j] = arr[j - 1]; arr[j - 1] = tmp; } else { break; } } } } /// /// sort list. /// static public void InsertionSort(this IList arr, Func comparison) { InsertionSort(arr, (a, b) => comparison(a, b) ? 1 : -1); } /// /// insert value to dictionary, if key is exist, replace value. /// static public void SafeInsert(this IDictionary dic, TKey key, TValue value) { if (dic.ContainsKey(key)) dic[key] = value; else dic.Add(key, value); } /// /// insert value to dictionary, if key is exist, replace value. /// static public void SafeInsert(this IDictionary dic, KeyValuePair kvPair) { SafeInsert(dic, kvPair.Key, kvPair.Value); } /// /// get value from dictionary, if key is not exist, return default value. /// static public TValue SafeGet(this IDictionary dic, TKey key) { if (dic.ContainsKey(key)) return dic[key]; else return default; } static public bool TryGetRandomValue(this IDictionary dic, out TValue result) { result = default; int rnd = UnityEngine.Random.Range(0, dic.Count); foreach (var kv in dic) { if (rnd-- == 0) { result = kv.Value; return true; } } return false; } /// /// get value from list, if index less than 0, return first value. if index greater than list count, return last value. /// static public TValue ClampGet(this IList list, int index) { if(list.Count == 0) throw new Exception("list is empty"); if(index < 0) return list[0]; else if (index >= list.Count) return list[list.Count - 1]; else return list[index]; } /// /// try get value from list, if index is not valid, return false. /// static public bool TryGetValueAt(this IList list, int index, out TValue result) { if(index >= 0 && index < list.Count) { result = list[index]; return true; } else { result = default; return false; } } static public bool TryFind(this IList list, Predicate match, out TValue result) { foreach(var item in list) { if(match(item)) { result = item; return true; } } result = default; return false; } static public bool TryBinarySearch(this IList list, TValue value, Comparison comparison, out int index) => TryBinarySearch(list, (v) => comparison(v, value), out index); static public bool TryBinarySearch(this IList list, Func comparison, out int index) { int low = 0; int high = list.Count - 1; index = -1; while (low <= high) { int mid = (low + high) / 2; int cmp = comparison(list[mid]); if (cmp == 0) { index = mid; break; } else if (cmp < 0) { low = mid + 1; } else { high = mid - 1; } } return index != -1; } /// /// try get random value from list, if list is empty, return false. /// static public bool TryGetRandomValue(this IList list, out TValue result) { if(list.Count == 0) { result = default; return false; } result = list[UnityEngine.Random.Range(0, list.Count)]; return true; } /// /// set elements with given range to value. /// static public void SetElements(this IList list, TValue value, int offset, int count) { for(int i = offset; i < offset + count; ++i) { if(i < 0 || i >= list.Count) continue; list[i] = value; } } /// /// set all elements to value. /// static public void SetElements(this IList list, TValue value) { SetElements(list, value, 0, list.Count); } /// /// swapping elements with predict /// static public int SwapElements(this IList list, Func predict) { const int needSetFlag = 0; const int trueFlag = 1; const int falseFlag = 2; int ret = -1; int[] flags = new int[list.Count]; for(int i = 0; i < list.Count; ++i) { if (flags[i] == needSetFlag) flags[i] = predict(list[i]) ? trueFlag : falseFlag; if (flags[i] == trueFlag) continue; int j; for(j = i + 1; j < list.Count; ++j) { if (flags[j] == needSetFlag) flags[j] = predict(list[j]) ? trueFlag : falseFlag; if (flags[j] == falseFlag) continue; TValue tmp = list[i]; list[i] = list[j]; list[j] = tmp; flags[i] = trueFlag; flags[j] = falseFlag; break; } ret = i; if(j == list.Count) break; } return ret; } static public void Shuffle(this IList list) { int n = list.Count; while (n > 1) { n--; int rndIdx = UnityEngine.Random.Range(0, n + 1); TValue tmp = list[rndIdx]; list[rndIdx] = list[n]; list[n] = tmp; } } public static bool EqualsUpToSeconds(this DateTime dt1, DateTime dt2) { return dt1.Year == dt2.Year && dt1.Month == dt2.Month && dt1.Day == dt2.Day && dt1.Hour == dt2.Hour && dt1.Minute == dt2.Minute && dt1.Second == dt2.Second; } public static BigInteger Multiply(this BigInteger a, float b) { return (a * (BigInteger)(b * 1000)) / 1000; } public static BigInteger Divide(this BigInteger a, float b) { return (a * 1000) / (BigInteger)(b * 1000); } }