using System; using System.Collections.Generic; namespace miew.Array { using SysArray = System.Array; public static class Extensions { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// remember to re-store the return value of this extension /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public static T[] RemoveAt<T>(this T[] arr, int idx) { int c = arr.Length; if (idx < 0 || idx >= c) throw new IndexOutOfRangeException(); T[] newarr = new T[c - 1]; SysArray.Copy(arr, 0, newarr, 0, idx); // part I. int i_src = idx + 1; SysArray.Copy(arr, i_src, newarr, idx, c - i_src); // part II. return newarr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// remember to re-store the return value of this extension /// Array.Resize always copies to a new array. Rather than sliding the original array and doing a /// resize, we'll just create the new array ourselves and avoid Array.Resize. /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public static T[] RemoveRange<T>(this T[] arr, int idx, int count) { int c = arr.Length; if (idx < 0 || idx >= c) throw new IndexOutOfRangeException(); if (count == 0) return arr; if (idx + count > c) throw new ArgumentOutOfRangeException(); T[] newarr = new T[c - count]; SysArray.Copy(arr, 0, newarr, 0, idx); // part I. int i_src = idx + count; SysArray.Copy(arr, i_src, newarr, idx, c - i_src); // part II. return newarr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public static bool ValueCompare<T>(this T[] a, T[] b) where T : struct { if (a.Length != b.Length) return false; EqualityComparer<T> q = EqualityComparer<T>.Default; for (int i = 0; i < a.Length; i++) if (!q.Equals(a[i], b[i])) return false; return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public static bool ValueCompare<T>(this T[] a, int a_offset, T[] b) where T : struct { if (a_offset >= a.Length || a_offset + b.Length > a.Length) return false; EqualityComparer<T> q = EqualityComparer<T>.Default; for (int i = 0; i < b.Length; i++, a_offset++) if (!q.Equals(a[a_offset], b[i])) return false; return true; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// In a list of objects of type T which are sorted in order based on type K, search for a value of type K. /// </summary> /// <remarks> /// http://www.removingalldoubt.com/permalink.aspx/f7e6feff-8257-4efe-ad64-acd1c7a4a1e3 /// </remarks> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public static int BinarySearch<T, K>(this IList<T> list, K value, Converter<T, K> convert, Comparison<K> compare) { int i = 0; int j = list.Count - 1; while (i <= j) { int m = i + (j - i) / 2; int r = compare(convert(list[m]), value); if (r == 0) return m; if (r < 0) i = m + 1; else j = m - 1; } return ~i; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// In a list of objects of type T which are sorted an order based on type K, search for a value of type K. /// </summary> /// <typeparam name="T">Type the objects in the list</typeparam> /// <typeparam name="K">Type of the key by by which the objects in the list are sorted</typeparam> /// <param name="list">IList interface handle to a list of objects of type T</param> /// <param name="item">Object of type K to search for</param> /// <param name="convert">Function which derives a key of type K from an object of type T</param> /// <returns> /// The zero-based index of the item in the list if it is found; otherwise, a negative number that is /// the bitwise complement of the index of the next element that is larger than item /// </returns> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public static int BinarySearch<T, K>(this IList<T> list, K item, Converter<T, K> convert) where K : IComparable<K> { return BinarySearch<T, K>(list, item, list.Count, convert); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Among the first 'c' elements of a list of objects of type T which are sorted an order based on type K, /// search for a value of type K. /// </summary> /// <typeparam name="T">Type the objects in the list</typeparam> /// <typeparam name="K">Type of the key by by which the objects in the list are sorted</typeparam> /// <param name="list">IList interface handle to a list of objects of type T</param> /// <param name="item">Object of type K to search for</param> /// <param name="c">Number of objects at the beginning of the list to search within</param> /// <param name="convert">Function which derives a key of type K from an object of type T</param> /// <returns> /// The zero-based index of the item in the list if it is found; otherwise, a negative number that is /// the bitwise complement of the index of the next element that is larger than item /// </returns> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public static int BinarySearch<T, K>(this IList<T> list, K item, int c, Converter<T, K> convert) where K : IComparable<K> { int i = 0; int j = c - 1; while (i <= j) { int m = i + (j - i) / 2; int r = convert(list[m]).CompareTo(item); if (r == 0) return m; if (r < 0) i = m + 1; else j = m - 1; } return ~i; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// /// </summary> /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static public void Swap<T>(this IList<T> rg, int i_l, int i_r) { if (i_l != i_r) { T temp = rg[i_r]; rg[i_r] = rg[i_l]; rg[i_l] = temp; } } }; }