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;
}
}
};
}