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