using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; namespace Cobilas.Collections { /// Array manipulation class. public static class ArrayManipulation { private readonly static Exception ArrayNullException = new ArgumentNullException("The array cannot be null."); // private readonly static Exception ArrayEmptyException = new ArgumentException("The array cannot be empty."); /// Insert a list of items at a given index into a target array. /// The items that will be inserted into the list. /// The index of the list where the items will be inserted. /// The list that will receive the items. /// public static T[] Insert(T[] itens, long index, T[] list) { if (itens is null) throw ArrayNullException; else if (itens.LongLength == 0) return list; list = list is null ? Array.Empty() : list; T[] newList = new T[list.LongLength + itens.LongLength]; Array.Copy(list, 0, newList, 0, index); Array.Copy(itens, 0, newList, index, itens.LongLength); Array.Copy(list, index, newList, itens.LongLength + index, list.LongLength - index); return newList; } /// Insert a list of items at a given index into a target array. /// The item that will be inserted into the list. /// The index of the list where the items will be inserted. /// The list that will receive the items. /// public static T[] Insert(T item, long index, T[] list) => Insert(new T[] { item }, index, list); /// Insert a list of items at a given index into a target array. /// The items that will be inserted into the list. /// The index of the list where the items will be inserted. /// The list that will receive the items. /// [Obsolete("Use the T[] Insert(IEnumerable, long, T[]) method")] public static T[] Insert(IEnumerator itens, long index, T[] list) { if (itens is null) throw ArrayNullException; while (itens.MoveNext()) list = Insert(itens.Current, index, list); return list; } /// Insert a list of items at a given index into a target array. /// The items that will be inserted into the list. /// The index of the list where the items will be inserted. /// The list that will receive the items. /// public static T[] Insert(IEnumerable collection, long index, T[] list) { if (collection is null) throw ArrayNullException; foreach (T item in collection) list = Insert(item, index, list); return list; } /// Insert a list of items at a given index into a target array. /// The items that will be inserted into the list. /// The index of the list where the items will be inserted. /// The list that will receive the items. /// public static void Insert(IEnumerable collection, long index, ref T[] list) => list = Insert(collection, index, list); /// Insert a list of items at a given index into a target array. /// The items that will be inserted into the list. /// The index of the list where the items will be inserted. /// The list that will receive the items. /// public static void Insert(T[] itens, long index, ref T[] list) => list = Insert(itens, index, list); /// Insert a list of items at a given index into a target array. /// The item that will be inserted into the list. /// The index of the list where the items will be inserted. /// The list that will receive the items. /// public static void Insert(T item, long index, ref T[] list) => list = Insert(item, index, list); /// Adds a list of items to the target list. /// The method does not add items that already exist in the target list. /// /// The item that will be inserted into the list. /// The list that will receive the items. /// This way, when adding the same object, the operation will not be performed /// and the list will be returned without being modified. /// public static T[] AddNon_Existing(T item, T[] list) { if (!Exists(item, list)) return Add(item, list); return list; } /// Adds a list of items to the target list. /// The method does not add items that already exist in the target list. /// /// The item that will be inserted into the list. /// The list that will receive the items. /// This way, when adding the same object, the operation will not be performed /// and the list will be returned without being modified. /// public static void AddNon_Existing(T item, ref T[] list) => list = AddNon_Existing(item, list); /// Adds a list of items to the target list. /// The items that will be inserted into the list. /// The list that will receive the items. /// public static T[] Add(T[] itens, T[] list) => Insert(itens, ArrayLongLength(list), list); /// Adds a list of items to the target list. /// The items that will be inserted into the list. /// The list that will receive the items. /// [Obsolete("Use the T[] Add(IEnumerable, T[]) method.")] public static T[] Add(IEnumerator itens, T[] list) => Insert(itens, ArrayLongLength(list), list); /// Adds a list of items to the target list. /// The items that will be inserted into the list. /// The list that will receive the items. /// [Obsolete("Use the T[] Add(IEnumerable, ref T[]) method.")] public static void Add(IEnumerator itens, ref T[] list) => list = Add(itens, list); /// Adds a list of items to the target list. /// The items that will be inserted into the list. /// The list that will receive the items. /// public static T[] Add(IEnumerable collection, T[] list) => Insert(collection, ArrayLongLength(list), list); /// Adds a list of items to the target list. /// The items that will be inserted into the list. /// The list that will receive the items. /// public static void Add(IEnumerable collection, ref T[] list) => list = Insert(collection, ArrayLongLength(list), list); /// Adds a list of items to the target list. /// The item that will be inserted into the list. /// The list that will receive the items. /// public static T[] Add(T item, T[] list) => Insert(item, ArrayLongLength(list), list); /// Adds a list of items to the target list. /// The items that will be inserted into the list. /// The list that will receive the items. /// public static void Add(T[] itens, ref T[] list) => Insert(itens, ArrayLongLength(list), ref list); /// Adds a list of items to the target list. /// The item that will be inserted into the list. /// The list that will receive the items. /// public static void Add(T item, ref T[] list) => Insert(item, ArrayLongLength(list), ref list); /// Remove items from the target list. /// The target index to remove from the target list. /// The length and number of items to remove from the list from the index. /// The list from which items will be removed. /// /// public static T[] Remove(long index, long length, T[] list) { if (list is null) throw ArrayNullException; else if (list.LongLength == 0) return list; T[] newList = new T[list.LongLength - length]; Array.Copy(list, 0, newList, 0, index); Array.Copy(list, index + length, newList, index, list.LongLength - (index + length)); return newList; } /// Remove items from the target list. /// The target index to remove from the target list. /// The length and number of items to remove from the list from the index. /// The list from which items will be removed. /// /// public static void Remove(long index, long length, ref T[] list) => list = Remove(index, length, list); /// Remove items from the target list. /// The target index to remove from the target list. /// The list from which items will be removed. /// /// public static T[] Remove(long index, T[] list) => Remove(index, 1L, list); /// Remove items from the target list. /// The target index to remove from the target list. /// The list from which items will be removed. /// /// public static void Remove(long index, ref T[] list) => list = Remove(index, list); /// Remove items from the target list. /// The target item to remove from the target list. /// The list from which items will be removed. /// /// public static T[] Remove(T item, T[] list) => Remove(LongIndexOf(item, list), list); /// Remove items from the target list. /// The target item to remove from the target list. /// The list from which items will be removed. /// /// public static void Remove(T item, ref T[] list) => list = Remove(item, list); /// Array cleaning. /// /// /// public static void ClearArray(Array array, long index, long length) { if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); else if (index < 0 || index >= array.LongLength) throw new ArgumentOutOfRangeException("index", new ArgumentOutOfRangeException()); else if (length < 0 || length > array.LongLength || index + length > array.LongLength) throw new ArgumentOutOfRangeException("length", new ArgumentOutOfRangeException()); for (long I = index; I < length; I++) array.SetValue(default, I); } /// Array cleaning. /// /// /// public static void LongClearArray(Array array) => ClearArray(array, 0L, ArrayLongLength(array)); /// Array cleaning. /// /// public static void ClearArray(Array array, int index, int length) => Array.Clear(array, index, length); /// Array cleaning. /// public static void ClearArray(Array array) => ClearArray(array, 0, array.Length); /// Array cleaning. /// /// /// public static void ClearArray(long index, long length, ref T[] array) { ClearArray(array, index, length); array = Array.Empty(); } /// Array cleaning. /// /// /// public static void LongClearArray(ref T[] array) => ClearArray(0, ArrayLongLength(array), ref array); /// Array cleaning. /// In addition to clearing the array, it returns an empty array. /// /// /// public static void ClearArray(int index, int length, ref T[] array) { Array.Clear(array, index, length); array = Array.Empty(); } /// Array cleaning. /// In addition to clearing the array, it returns an empty array. /// /// public static void ClearArray(ref T[] array) => ClearArray(0, array.Length, ref array); /// Array cleaning. /// It will only perform cleaning if the array is not null. /// /// /// /// public static void ClearArraySafe(Array array, long index, long length) { if (!EmpytArray(array)) ClearArray(array, index, length); } /// Array cleaning. /// It will only perform cleaning if the array is not null. /// /// /// /// public static void LongClearArraySafe(Array array) { if (!EmpytArray(array)) LongClearArray(array); } /// Array cleaning. /// It will only perform cleaning if the array is not null. /// /// public static void ClearArraySafe(Array array, int index, int length) { if (!EmpytArray(array)) ClearArray(array, index, length); } /// Array cleaning. /// It will only perform cleaning if the array is not null. /// public static void ClearArraySafe(Array array) { if (!EmpytArray(array)) ClearArray(array); } /// Array cleaning. /// In addition to clearing the array, it returns an empty array. /// It will only perform cleaning if the array is not null. /// /// /// /// public static void ClearArraySafe(long index, long length, ref T[] array) { if (!EmpytArray(array)) ClearArray(index, length, ref array); } /// Array cleaning. /// In addition to clearing the array, it returns an empty array. /// It will only perform cleaning if the array is not null. /// /// /// /// public static void LongClearArraySafe(ref T[] array) { if (!EmpytArray(array)) LongClearArray(ref array); } /// Array cleaning. /// In addition to clearing the array, it returns an empty array. /// It will only perform cleaning if the array is not null. /// /// public static void ClearArraySafe(int index, int length, ref T[] array) { if (!EmpytArray(array)) ClearArray(index, length, ref array); } /// Array cleaning. /// In addition to clearing the array, it returns an empty array. /// It will only perform cleaning if the array is not null. /// public static void ClearArraySafe(ref T[] array) { if (!EmpytArray(array)) ClearArray(ref array); } /// Separate a list into two using an index. /// The list that will be separated. /// The index where the list will be separated. /// /// /// /// /// public static void SeparateList(T[] array, long separationIndex, out T[] part1, out T[] part2) { long arrayLength = ArrayManipulation.ArrayLongLength(array); if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); else if (arrayLength == 0) { part1 = part2 = Array.Empty(); } else if (separationIndex < 0 || !(separationIndex < arrayLength)) throw new ArgumentOutOfRangeException("separationIndex", new ArgumentOutOfRangeException()); Array.Copy(array, 0, part1 = new T[separationIndex + 1], 0, separationIndex + 1); Array.Copy(array, separationIndex + 1, part2 = new T[array.LongLength - (separationIndex + 1)], 0, array.LongLength - (separationIndex + 1)); } /// This function performs a cut in a list. /// The index where the clipping will begin. /// The index where the clipping will begin. /// The list that will be cut. /// The function will return a list of items that were cut from the original list. The original list will not be modified. /// /// /// public static T[] TakeStretch(long index, long length, T[] list) { if (list is null) throw ArrayNullException; else if (list.LongLength == 0) throw new ArgumentException("The array cannot be empty."); T[] Res = new T[length]; CopyTo(list, index, Res, 0, length); return Res; } /// /// Turn a list into a read-only list /// public static ReadOnlyCollection ReadOnly(T[] list) => Array.AsReadOnly(list); /// /// Turn a list into a read-only list /// /// If the list is null, it will return an empty read-only list. public static ReadOnlyCollection ReadOnlySafe(T[] list) => list is null ? new ReadOnlyCollection(Array.Empty()) : ReadOnly(list); /// /// Searches for the specified object and returns the index of its first occurrence in a one-dimensional array or a range of elements in the array. /// public static long IndexOf(object item, Array array, long index, long length) { if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); else if (index < 0 || index >= array.LongLength) throw new ArgumentOutOfRangeException("index", new ArgumentOutOfRangeException()); else if (length < 0 || length > array.LongLength || index + length > array.LongLength) throw new ArgumentOutOfRangeException("length", new ArgumentOutOfRangeException()); else if (array.LongLength == 0) return -1; object[] obj_array = array as object[]; long endIndex = index + length; if (obj_array != null) { for (long I = index; I < endIndex; I++) if (item is null) { if (obj_array[I] is null) return I; } else { object temp = obj_array[I]; if (temp != null && temp.Equals(item)) return I; } } else { for (long I = index; I < endIndex; I++) { object temp = array.GetValue(I); if (item is null) { if (temp is null) return I; } else { if (temp != null && temp.Equals(item)) return I; } } } return -1L; } /// /// Searches for the specified object and returns the index of its first occurrence in a one-dimensional array or a range of elements in the array. /// public static long IndexOf(object item, Array array, long index) { if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); return IndexOf(item, array, index, array.LongLength - index); } /// /// Searches for the specified object and returns the index of its first occurrence in a one-dimensional array or a range of elements in the array. /// public static long LongIndexOf(object item, Array array) => IndexOf(item, array, 0L); /// /// Searches for the specified object and returns the index of its first occurrence in a one-dimensional array or a range of elements in the array. /// public static int IndexOf(object item, Array array, int index, int length) => Array.IndexOf(array, item, index, length); /// /// Searches for the specified object and returns the index of its first occurrence in a one-dimensional array or a range of elements in the array. /// public static int IndexOf(object item, Array array, int index) => Array.IndexOf(array, item, index); /// /// Searches for the specified object and returns the index of its first occurrence in a one-dimensional array or a range of elements in the array. /// public static int IndexOf(object item, Array array) => Array.IndexOf(array, item); /// /// Returns the index of the last occurrence of a value in a one-dimensional Array or part of the Array. /// public static long LastIndexOf(object item, Array array, long index, long length) { if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); else if (index < 0 || index >= array.LongLength) throw new ArgumentOutOfRangeException("index", new ArgumentOutOfRangeException()); else if (length < 0 || length > array.LongLength || index + length > array.LongLength) throw new ArgumentOutOfRangeException("length", new ArgumentOutOfRangeException()); else if (array.LongLength == 0) return -1; object[] obj_array = array as object[]; long endIndex = length; if (obj_array != null) { for (long I = index; I >= endIndex ; I--) if (item is null) { if (obj_array[I] is null) return I; } else { object temp = obj_array[I]; if (temp != null && temp.Equals(item)) return I; } } else { for (long I = index; I >= endIndex ; I--) { object temp = array.GetValue(I); if (item is null) { if (temp is null) return I; } else { if (temp != null && temp.Equals(item)) return I; } } } return -1L; } /// /// Returns the index of the last occurrence of a value in a one-dimensional Array or part of the Array. /// public static long LastIndexOf(object item, Array array, long index) { if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); return LastIndexOf(item, array, array.LongLength - index, index); } /// /// Returns the index of the last occurrence of a value in a one-dimensional Array or part of the Array. /// public static long LongLastIndexOf(object item, Array array) => LastIndexOf(item, array, 0L); /// /// Returns the index of the last occurrence of a value in a one-dimensional Array or part of the Array. /// public static int LastIndexOf(object item, Array array, int index, int length) => Array.LastIndexOf(array, item, index, length); /// /// Returns the index of the last occurrence of a value in a one-dimensional Array or part of the Array. /// public static int LastIndexOf(object item, Array array, int index) => Array.LastIndexOf(array, item, index); /// /// Returns the index of the last occurrence of a value in a one-dimensional Array or part of the Array. /// public static int LastIndexOf(object item, Array array) => Array.LastIndexOf(array, item); /// /// Searches for an element that matches the conditions defined by the specified predicate and returns /// the zero-based index of the first occurrence within the range of elements in the Array that starts /// at the specified index and contains the specified number of elements. /// /// /// /// public static long FindIndex(T[] array, long index, long length, Predicate match) { long arrayLength = ArrayManipulation.ArrayLongLength(array); if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (match == null) throw new ArgumentNullException("match", new ArgumentNullException()); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); else if (arrayLength == 0) return -1; else if (length < 0 || length > arrayLength) throw new ArgumentOutOfRangeException("length", new ArgumentOutOfRangeException()); else if (index < 0 || !(index < arrayLength)) throw new ArgumentOutOfRangeException("index", new ArgumentOutOfRangeException()); for (long I = index; I < length; I++) if (match(array[I])) return I; return -1; } /// /// Searches for an element that matches the conditions defined by the specified predicate and returns /// the zero-based index of the first occurrence within the range of elements in the Array that starts /// at the specified index and contains the specified number of elements. /// /// /// /// public static long FindIndex(T[] array, long index, Predicate match) { if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); return FindIndex(array, index, array.LongLength, match); } /// /// Searches for an element that matches the conditions defined by the specified predicate and returns /// the zero-based index of the first occurrence within the range of elements in the Array that starts /// at the specified index and contains the specified number of elements. /// /// /// /// public static long LongFindIndex(T[] array, Predicate match) => FindIndex(array, 0L, match); /// /// Searches for an element that matches the conditions defined by the specified predicate and returns /// the zero-based index of the first occurrence within the range of elements in the Array that starts /// at the specified index and contains the specified number of elements. /// public static int FindIndex(T[] array, int index, int length, Predicate match) => Array.FindIndex(array, index, length, match); /// /// Searches for an element that matches the conditions defined by the specified predicate and returns /// the zero-based index of the first occurrence within the range of elements in the Array that starts /// at the specified index and contains the specified number of elements. /// public static int FindIndex(T[] array, int index, Predicate match) => Array.FindIndex(array, index, match); /// /// Searches for an element that matches the conditions defined by the specified predicate and returns /// the zero-based index of the first occurrence within the range of elements in the Array that starts /// at the specified index and contains the specified number of elements. /// public static int FindIndex(T[] array, Predicate match) => Array.FindIndex(array, match); /// /// Searches for an element that matches the conditions defined by a /// specified predicate and returns the zero-based index of the last /// occurrence in an Array or part of it. /// /// /// /// public static long FindLastIndex(T[] array, long index, long length, Predicate match) { long arrayLength = ArrayManipulation.ArrayLongLength(array); if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (match == null) throw new ArgumentNullException("match", new ArgumentNullException()); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); else if (arrayLength == 0) return -1; else if (length < 0 || length > arrayLength) throw new ArgumentOutOfRangeException("length", new ArgumentOutOfRangeException()); else if (index < 0 || !(index < arrayLength)) throw new ArgumentOutOfRangeException("index", new ArgumentOutOfRangeException()); long startIndex = length - index; for (long I = startIndex - 1; I >= index ; I--) if (match(array[I])) return I; return -1; } /// /// Searches for an element that matches the conditions defined by a /// specified predicate and returns the zero-based index of the last /// occurrence in an Array or part of it. /// /// /// /// public static long FindLastIndex(T[] array, long index, Predicate match) { if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); return FindLastIndex(array, index, array.LongLength, match); } /// /// Searches for an element that matches the conditions defined by a /// specified predicate and returns the zero-based index of the last /// occurrence in an Array or part of it. /// /// /// /// public static long LongFindLastIndex(T[] array, Predicate match) => FindLastIndex(array, 0L, match); /// /// Searches for an element that matches the conditions defined by a /// specified predicate and returns the zero-based index of the last /// occurrence in an Array or part of it. /// /// /// /// public static int FindLastIndex(T[] array, int index, int length, Predicate match) => Array.FindLastIndex(array, index, length, match); /// /// Searches for an element that matches the conditions defined by a /// specified predicate and returns the zero-based index of the last /// occurrence in an Array or part of it. /// /// /// /// public static int FindLastIndex(T[] array, int index, Predicate match) => Array.FindLastIndex(array, index, match); /// /// Searches for an element that matches the conditions defined by a /// specified predicate and returns the zero-based index of the last /// occurrence in an Array or part of it. /// /// /// /// public static int FindLastIndex(T[] array, Predicate match) => Array.FindLastIndex(array, match); /// /// Searches for an element that matches the conditions defined by the /// specified predicate and returns the first occurrence in the entire Array. /// /// /// public static T FindLast(T[] array, Predicate match) { if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (match == null) throw new ArgumentNullException("match", new ArgumentNullException()); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); for (long I = array.LongLength - 1; I >= 0 ; I--) if (match(array[I])) return array[I]; return default; } /// /// Retrieves all elements that match the conditions defined by the specified predicate. /// /// /// public static T[] FindAll(T[] array, Predicate match) { if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (match == null) throw new ArgumentNullException("match", new ArgumentNullException()); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); T[] outArray = new T[0]; for (long I = 0; I < array.LongLength; I++) if (match(array[I])) outArray = Add(array[I], outArray); return outArray; } /// /// Searches for an element that matches the conditions defined by the /// specified predicate, and returns the first occurrence within the entire Array. /// /// /// public static T Find(T[] array, Predicate match) { if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (match == null) throw new ArgumentNullException("match", new ArgumentNullException()); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); for (long I = 0; I < array.LongLength; I++) if (match(array[I])) return array[I]; return default; } /// /// Determines whether the specified array contains elements that match the conditions defined by the specified predicate. /// [Obsolete("Use bool:Exists(T[], Predicate)")] public static bool Exists(object item, Array array) { for (long I = 0; I < ArrayLongLength(array); I++) if (array.GetValue(I) == item) return true; return false; } /// /// Determines whether the specified array contains elements that match the conditions defined by the specified predicate. /// public static bool Exists(T[] array, Predicate match) => LongFindIndex(array, match) != -1; /// /// Determines whether the specified array contains elements that match the conditions defined by the specified predicate. /// public static bool Exists(T item, T[] array) => Exists(array, IT => EqualityComparer.Default.Equals(IT, item)); /// /// Copies all the elements of the current one-dimensional array to the specified one-dimensional array. /// public static void CopyTo(Array sourceArray, long sourceIndex, Array destinationArray, long destinationIndex, long length) => Array.Copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length); /// /// Copies all the elements of the current one-dimensional array to the specified one-dimensional array. /// public static void CopyTo(Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length) => CopyTo(sourceArray, (long)sourceIndex, destinationArray, (long)destinationIndex, (long)length); /// /// Copies all the elements of the current one-dimensional array to the specified one-dimensional array. /// public static void CopyTo(Array sourceArray, Array destinationArray, long length) => CopyTo(sourceArray, 0, destinationArray, 0, length); /// /// Copies all the elements of the current one-dimensional array to the specified one-dimensional array. /// public static void CopyTo(Array sourceArray, Array destinationArray, int length) => CopyTo(sourceArray, 0, destinationArray, 0, length); /// /// Copies all the elements of the current one-dimensional array to the specified one-dimensional array. /// public static void CopyTo(Array sourceArray, Array destinationArray) => CopyTo(sourceArray, 0, destinationArray, 0, sourceArray.Length); /// Converts an array of one type to an array of another type. /// The type of the elements of the source array. /// The type of the elements of the target array. /// The one-dimensional, zero-based to convert to a target type. /// A that converts each element from one type to another type. /// An array of the target type containing the converted elements from the source array. /// public static TOutput[] ConvertAll(TInput[] array, Converter converter) => Array.ConvertAll(array, converter); /// Converts an array of one type to an array of another type. /// The type of the elements of the source array. /// The type of the elements of the target array. /// The one-dimensional, zero-based to convert to a target type. /// A that converts each element from one type to another type. /// An array of the target type containing the converted elements from the source array. /// /// public static TOutput[] LongConvertAll(TInput[] array, Converter converter) { if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (converter == null) throw new ArgumentNullException("converter", new ArgumentNullException()); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); TOutput[] output = new TOutput[array.LongLength]; for (long I = 0; I < array.LongLength; I++) output[I] = converter(array[I]); return output; } /// /// Reverses the order of the elements in a one-dimensional Array or in a portion of the Array. /// /// The one-dimensional Array to reverse. /// The starting index of the section to reverse. /// The number of elements in the section to reverse. public static void Reverse(Array array, int index, int length) => Array.Reverse(array, index, length); /// /// Reverses the order of the elements in a one-dimensional Array or in a portion of the Array. /// /// The one-dimensional Array to reverse. /// The starting index of the section to reverse. /// The number of elements in the section to reverse. /// /// /// public static void Reverse(Array array, long index, long length) { if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); else if (index < 0 || index >= array.LongLength) throw new ArgumentOutOfRangeException("index", new ArgumentOutOfRangeException()); else if (length < 0 || length > array.LongLength || index + length - 1 > array.LongLength) throw new ArgumentOutOfRangeException("length", new ArgumentOutOfRangeException()); object[] obj_array = array as object[]; if (obj_array != null) { for (long I = index, J = index + length - 1; I < J; I++, J--) { object temp = obj_array[I]; obj_array[I] = obj_array[J]; obj_array[J] = temp; } } else { for (long I = index, J = index + length - 1; I < J; I++, J--) { object temp = array.GetValue(I); array.SetValue(array.GetValue(J), I); array.SetValue(temp, J); } } } /// /// Reverses the order of the elements in a one-dimensional Array or in a portion of the Array. /// /// The one-dimensional Array to reverse. public static void Reverse(Array array) => Array.Reverse(array, 0, array.Length); /// /// Reverses the order of the elements in a one-dimensional Array or in a portion of the Array. /// /// The one-dimensional Array to reverse. public static void LongReverse(Array array) => Reverse(array, 0L, array.LongLength); /// /// Changes the number of elements of a one-dimensional array to the specified new size. /// public static void Resize(ref T[] array, int newSize) => Array.Resize(ref array, newSize); /// /// Changes the number of elements of a one-dimensional array to the specified new size. /// /// public static void Resize(ref T[] array, long newSize) { if (newSize < 0) throw new ArgumentOutOfRangeException("The \"newSize\" parameter cannot be less than zero."); T[] l_array = array; if (l_array == null) { array = new T[newSize]; } else { T[] newArray = new T[newSize]; CopyTo(l_array, 0L, newArray, 0L, l_array.LongLength > newSize ? newSize : l_array.LongLength); array = newArray; } } /// /// Determines whether the collection is empty or null. /// public static bool EmpytArray(ICollection array) => array is null || array.Count == 0; /// /// Determines whether the collection is empty or null. /// public static bool EmpytArray(ILongCollection array) => array is null || array.Count == 0; /// /// Determines the length of a collection. /// public static int ArrayLength(ICollection array) => array is null ? 0 : array.Count; /// /// Determines the length of an Array. /// public static long ArrayLongLength(Array array) => array is null ? 0L : array.LongLength; /// /// Determines the length of an Array. /// public static long ArrayLongLength(ILongCollection array) => array is null ? 0L : array.Count; /// /// Determines whether the collection is read-only. /// public static bool IsReadOnlySafe(IList array) => !(array is null) && array.IsReadOnly; /// /// Determines whether the collection is read-only. /// public static bool IsReadOnlySafe(ILongList array) => !(array is null) && array.IsReadOnly; /// /// Determines whether the collection has a fixed size. /// public static bool IsFixedSizeSafe(IList array) => !(array is null) && array.IsFixedSize; /// /// Determines whether the collection has a fixed size. /// public static bool IsFixedSizeSafe(ILongList array) => !(array is null) && array.IsFixedSize; /// /// Determines whether the collection is synchronized. /// public static bool IsSynchronizedSafe(ICollection collection) => !(collection is null) && collection.IsSynchronized; /// /// Determines whether the collection is synchronized. /// public static bool IsSynchronizedSafe(ILongCollection collection) => !(collection is null) && collection.IsSynchronized; /// The method traverses several parts of a list simultaneously. /// The array that will be read. /// Action that receives the object and the index of the list. /// The number of sectors to read. /// /// public static void ForSector(Array array, in Action action, in long sectorCount) { if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); else if (sectorCount < 1) throw new ArgumentOutOfRangeException("The \"sectorCount\" parameter cannot be less than one."); else if (array.Rank != 1) throw new RankException("The array cannot be multi-dimensional."); SectorStatus[] sectors = new SectorStatus[sectorCount]; // if (sectorCount != 1) // for(long I = 0; I < sectorCount; I++) // sectors[I] = new SectorStatus(I * sectorCount, (I + 1) * sectorCount); // sectors[sectorCount - 1] = new SectorStatus((sectorCount - 1) * sectorCount, array.LongLength - 1); long index = 0L; bool confirmations = true; bool preConfirmations = false; while(confirmations) { if (!sectors[index].Init) { if (index == sectorCount - 1) sectors[sectorCount - 1] = new SectorStatus((sectorCount - 1) * sectorCount, array.LongLength - 1); else sectors[index] = new SectorStatus(index * sectorCount, (index + 1) * sectorCount); sectors[index].Init = true; } if (!sectors[index].BrokenCount) { preConfirmations = true; action((T)array.GetValue(sectors[index].CurrentIndex), sectors[index].CurrentIndex); sectors[index].Next(); } index++; if (index >= sectorCount) { index = 0L; confirmations = preConfirmations; preConfirmations = false; } } } /// The method traverses several parts of a list simultaneously. /// The array that will be read. /// Action that receives the object and the index of the list. /// /// public static void ForSector(Array array, in Action action) { if (array == null) throw new ArgumentNullException("array", new ArgumentNullException()); ForSector(array, in action, (long)Math.Sqrt(array.LongLength)); } /// The method traverses several parts of a list simultaneously. /// The array that will be read. /// Action that receives the object and the index of the list. /// The number of sectors to read. /// /// public static void ForSector(T[] array, in Action action, in long sectorCount) => ForSector((Array)array, action, sectorCount); /// The method traverses several parts of a list simultaneously. /// The array that will be read. /// Action that receives the object and the index of the list. /// /// public static void ForSector(T[] array, in Action action) => ForSector((Array)array, action); /// The method traverses several parts of a list simultaneously. /// The array that will be read. /// Action that receives the object and the index of the list. /// The number of sectors to read. /// /// public static void ForSector(Array array, in Action action, in long sectorCount) => ForSector(array, action, sectorCount); /// The method traverses several parts of a list simultaneously. /// The array that will be read. /// Action that receives the object and the index of the list. /// /// public static void ForSector(Array array, in Action action) => ForSector(array, action); /// The method traverses several parts of a list simultaneously. /// The array that will be read. /// Action that receives the object and the index of the list. /// The number of sectors to read. /// /// public static void ForSector(IList list, in Action action, in int sectorCount) { if (list == null) throw new ArgumentNullException("list", new ArgumentNullException()); else if (sectorCount < 1) throw new ArgumentOutOfRangeException("The \"sectorCount\" parameter cannot be less than one."); SectorStatus[] sectors = new SectorStatus[sectorCount]; long index = 0L; bool confirmations = true; bool preConfirmations = false; while(confirmations) { if (!sectors[index].Init) { if (index == sectorCount - 1) sectors[sectorCount - 1] = new SectorStatus((sectorCount - 1) * sectorCount, list.Count - 1); else sectors[index] = new SectorStatus(index * sectorCount, (index + 1) * sectorCount); sectors[index].Init = true; } if (!sectors[index].BrokenCount) { preConfirmations = true; action((T)list[(int)sectors[index].CurrentIndex], (int)sectors[index].CurrentIndex); sectors[index].Next(); } index++; if (index >= sectorCount) { index = 0L; confirmations = preConfirmations; preConfirmations = false; } } } /// The method traverses several parts of a list simultaneously. /// The array that will be read. /// Action that receives the object and the index of the list. /// /// public static void ForSector(IList list, in Action action) { if (list == null) throw new ArgumentNullException("list", new ArgumentNullException()); ForSector(list, in action, (int)Math.Sqrt(list.Count)); } /// The method traverses several parts of a list simultaneously. /// The array that will be read. /// Action that receives the object and the index of the list. /// The number of sectors to read. /// /// public static void ForSector(IList list, in Action action, in int sectorCount) => ForSector((IList)list, action, sectorCount); /// The method traverses several parts of a list simultaneously. /// The array that will be read. /// Action that receives the object and the index of the list. /// /// public static void ForSector(IList list, in Action action) => ForSector((IList)list, action); /// The method traverses several parts of a list simultaneously. /// The array that will be read. /// Action that receives the object and the index of the list. /// The number of sectors to read. /// /// public static void ForSector(IList list, in Action action, in int sectorCount) => ForSector(list, action, sectorCount); /// The method traverses several parts of a list simultaneously. /// The array that will be read. /// Action that receives the object and the index of the list. /// /// public static void ForSector(IList list, in Action action) => ForSector(list, action); private struct SectorStatus { private bool init; private long index; private readonly long count; public long CurrentIndex => index; public bool BrokenCount => index >= count; public bool Init { get => init; set => init = value; } public SectorStatus(long index, long count) { this.init = false; this.index = index; this.count = count; } public SectorStatus(long count) : this(0L, count) {} public void Next() { if (BrokenCount) return; index++; } } } }