Add IList<T>.RemoveRange(Range)

This commit is contained in:
Oliver Booth 2022-06-03 11:53:40 +01:00
parent 5be42fea5a
commit 3d896ea5d1
No known key found for this signature in database
GPG Key ID: 32A00B35503AF634
5 changed files with 125 additions and 16 deletions

View File

@ -4,6 +4,7 @@
### Added
- X10D: Added `MathUtility.InverseLerp(float, float, float)` and `MathUtility.InverseLerp(double, double, double)`
- X10D: Added `Circle`, `CircleF`, `Cuboid`, `Ellipse`, `EllipseF`, `Line3D`, `Line`, `LineF`, `Polygon`, `PolygonF`, `Polyhedron`, and `Sphere`, to complement System.Drawing structs such as `Point` and `Rectangle`
- X10D: Added `IList<T>.RemoveRange(Range)`
- X10D: Added `Point.ToSize()`
- X10D: Added `Point.ToSizeF()`
- X10D: Added `Point.ToVector2()`

View File

@ -79,6 +79,63 @@ public class ListTests
Assert.ThrowsException<ArgumentNullException>(() => list!.Fill(0, 0, 0));
}
[TestMethod]
public void Random_ShouldReturnContainedObject_GivenNotNull()
{
var list = new List<int>(Enumerable.Range(1, 52)); // 52! chance of being shuffled to the same order
int random = list.Random();
Assert.IsTrue(list.Contains(random));
}
[TestMethod]
public void Random_ShouldThrow_GivenNull()
{
Assert.ThrowsException<ArgumentNullException>(() => ((List<int>?)null)!.Random());
}
[TestMethod]
public void RemoveRange_ShouldThrowArgumentNullException_GivenNull()
{
Assert.ThrowsException<ArgumentNullException>(() => ((List<int>?)null)!.RemoveRange(new Range()));
}
[TestMethod]
public void RemoveRange_ShouldThrowArgumentException_GivenEndIndexLessThanStart()
{
Assert.ThrowsException<ArgumentException>(() => new List<int>().RemoveRange(2..0));
}
[TestMethod]
public void RemoveRange_ShouldThrowArgumentOutOfRangeException_GivenEndIndexGreaterThanOrEqualToCount()
{
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new List<int>().RemoveRange(..0));
Assert.ThrowsException<ArgumentOutOfRangeException>(() => new List<int> {1}.RemoveRange(..2));
}
[TestMethod]
public void RemoveRange_ShouldRemoveElements_GivenList()
{
var list = new List<int>
{
1,
2,
3,
4,
5,
6,
7,
8,
9,
10
};
Assert.AreEqual(10, list.Count);
list.RemoveRange(2..5);
Assert.AreEqual(6, list.Count);
CollectionAssert.AreEqual(new[] {1, 2, 7, 8, 9, 10}, list);
}
[TestMethod]
public void Shuffle_ShouldReorder_GivenNotNull()
{
@ -97,19 +154,4 @@ public class ListTests
{
Assert.ThrowsException<ArgumentNullException>(() => ((List<int>?)null)!.Shuffle());
}
[TestMethod]
public void Random_ShouldReturnContainedObject_GivenNotNull()
{
var list = new List<int>(Enumerable.Range(1, 52)); // 52! chance of being shuffled to the same order
int random = list.Random();
Assert.IsTrue(list.Contains(random));
}
[TestMethod]
public void Random_ShouldThrow_GivenNull()
{
Assert.ThrowsException<ArgumentNullException>(() => ((List<int>?)null)!.Random());
}
}

View File

@ -1,4 +1,4 @@
using System.Diagnostics.Contracts;
using System.Diagnostics.Contracts;
using X10D.Core;
namespace X10D.Collections;
@ -119,6 +119,48 @@ public static class ListExtensions
return random.NextFrom(source);
}
/// <summary>
/// Removes a range of elements from the list.
/// </summary>
/// <param name="source">The list whose elements to remove.</param>
/// <param name="range">The range of elements to remove.</param>
/// <typeparam name="T">The type of the elements in <paramref name="source" />.</typeparam>
/// <exception cref="ArgumentNullException"><paramref name="source" /> is <see langword="null" />.</exception>
/// <exception cref="ArgumentException"><paramref name="range" /> defines an invalid range.</exception>
/// <exception cref="ArgumentOutOfRangeException">
/// <paramref name="range" /> defines an end index whose value is greater than or equal to the count of elements in the
/// list.
/// </exception>
public static void RemoveRange<T>(this IList<T> source, Range range)
{
#if NET6_0_OR_GREATER
ArgumentNullException.ThrowIfNull(source);
#else
if (source is null)
{
throw new ArgumentNullException(nameof(source));
}
#endif
int start = range.Start.IsFromEnd ? source.Count - range.Start.Value : range.Start.Value;
int end = range.End.IsFromEnd ? source.Count - range.End.Value : range.End.Value;
if (end < start)
{
throw new ArgumentException(ExceptionMessages.EndIndexLessThanStartIndex);
}
if (end >= source.Count)
{
throw new ArgumentOutOfRangeException(nameof(range), ExceptionMessages.EndIndexGreaterThanCount);
}
for (int index = end; index >= start; index--)
{
source.RemoveAt(index);
}
}
/// <summary>
/// Reorganizes the elements in a list by implementing a Fisher-Yates shuffle.
/// </summary>

View File

@ -78,6 +78,24 @@ namespace X10D {
}
}
/// <summary>
/// Looks up a localized string similar to The end index must be less than the list count..
/// </summary>
internal static string EndIndexGreaterThanCount {
get {
return ResourceManager.GetString("EndIndexGreaterThanCount", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The end index must be greater than or equal to the start index..
/// </summary>
internal static string EndIndexLessThanStartIndex {
get {
return ResourceManager.GetString("EndIndexLessThanStartIndex", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to HashAlgorithm&apos;s Create method returned null reference..
/// </summary>

View File

@ -26,6 +26,12 @@
<data name="BufferTooSmall" xml:space="preserve">
<value>The buffer is too small to contain the data.</value>
</data>
<data name="EndIndexLessThanStartIndex" xml:space="preserve">
<value>The end index must be greater than or equal to the start index.</value>
</data>
<data name="EndIndexGreaterThanCount" xml:space="preserve">
<value>The end index must be less than the list count.</value>
</data>
<data name="TypeIsNotClass" xml:space="preserve">
<value>{0} is not a class.</value>
</data>