using System; using System.Collections.Generic; using System.Linq; namespace Chernobyl.Collections.Generic { /// /// Extension and utility methods for the and related types. /// public static class List { /// /// Returns an empty . /// public static List Empty() => new List(); /// /// Removes the first item in the list where returns true. /// /// True if an item was removed, false if otherwise. public static bool RemoveFirst(this IList list, Predicate predicate) { var removeIndex = list.IndexWhere(predicate); if (removeIndex != -1) { list.RemoveAt(removeIndex); return true; } return false; } /// /// Removes and returns the item at the specified index. /// /// The type of the items contained within the list. /// The list that is to be modified. /// The index at which to remove and return the item from. This /// value cannot be less than zero or greater than or equal to the lists length. /// The value at the specified index in the list. /// Thrown when /// is out of range. public static T Pull(this IList list, int index) { // Note: We do not error check the index because the list's indexer will // already do this. var value = list[index]; list.RemoveAt(index); return value; } /// /// Removes and returns the items at the specified index. /// /// The type of the items contained within the list. /// The list that is to be modified. /// The index at which to remove and return the item from. This /// value cannot be less than zero or greater than or equal to the lists length. /// The number of items to return /// The value at the specified index in the list. /// Thrown when /// is out of range. public static IEnumerable Pull(this IList list, int index, int count) { return Enumerable.From(() => list.Pull(index)).Take(count); } /// /// Removes and returns the item at the specified index. /// /// The type of the items contained within the list. /// The list that is to be modified. /// The instance that will determine the indices at which to remove and /// return the item from. /// The number of items to extract from the list. /// The value at the specified index in the list. public static IEnumerable Pull(this IList list, Random random, int count) { count.Throw(nameof(count)).IfLessThan(0).IfGreaterThan(list.Count, "list.Count"); for (int i = 0; i < count; i++) yield return list.Pull(random.Next(list.Count)); } /// /// Returns the element at a specified index in a sequence or a default value if the index /// is out of range. This method performs the same function as /// /// but is optimized for . /// public static T AtOrDefault(this IList list, int index) => list.IsInBounds(index) ? list[index] : default; } }