mirror of
https://github.com/oliverbooth/X10D
synced 2024-11-09 23:25:43 +00:00
Add more LINQ-esque methods
* IEnumerable<T>.CountWhereNot(Func<T, bool>) * IEnumerable<T>.FirstWhereNot(Func<T, bool>) * IEnumerable<T>.FirstWhereNotOrDefault(Func<T, bool>) * IEnumerable<T>.LastWhereNot(Func<T, bool>) * IEnumerable<T>.LastWhereNotOrDefault(Func<T, bool>) * IEnumerable<T>.WhereNot(Func<T, bool>)
This commit is contained in:
parent
580f044511
commit
3847d53120
@ -11,6 +11,12 @@
|
||||
- X10D: Added `Color.GetClosestConsoleColor()`
|
||||
- X10D: Added `DateTime.GetIso8601WeekOfYear()` and `DateTimeOffset.GetIso8601WeekOfYear()`
|
||||
- X10D: Added `DirectoryInfo.Clear([bool])`
|
||||
- X10D: Added `IEnumerable<T>.CountWhereNot(Func<T, bool>)`
|
||||
- X10D: Added `IEnumerable<T>.FirstWhereNot(Func<T, bool>)`
|
||||
- X10D: Added `IEnumerable<T>.FirstWhereNotOrDefault(Func<T, bool>)`
|
||||
- X10D: Added `IEnumerable<T>.LastWhereNot(Func<T, bool>)`
|
||||
- X10D: Added `IEnumerable<T>.LastWhereNotOrDefault(Func<T, bool>)`
|
||||
- X10D: Added `IEnumerable<T>.WhereNot(Func<T, bool>)`
|
||||
- X10D: Added `IList<T>.RemoveRange(Range)`
|
||||
- X10D: Added `IList<T>.Swap(IList<T>)` (#62)
|
||||
- X10D: Added `Point.IsOnLine(LineF)`, `Point.IsOnLine(PointF, PointF)`, and `Point.IsOnLine(Vector2, Vector2)`
|
||||
|
@ -1,11 +1,40 @@
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using X10D.Collections;
|
||||
using X10D.Core;
|
||||
|
||||
namespace X10D.Tests.Collections;
|
||||
|
||||
[TestClass]
|
||||
public class EnumerableTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void CountWhereNot_ShouldReturnCorrectCount_GivenSequence()
|
||||
{
|
||||
var enumerable = new[] {2, 4, 6, 7, 8, 9, 10};
|
||||
int count = enumerable.CountWhereNot(x => x % 2 == 0);
|
||||
Assert.AreEqual(2, count);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CountWhereNot_ShouldThrowArgumentNullException_GivenNullSource()
|
||||
{
|
||||
Assert.ThrowsException<ArgumentNullException>(() => ((IEnumerable<int>?)null)!.CountWhereNot(x => x % 2 == 0));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CountWhereNot_ShouldThrowOverflowException_GivenLargeSource()
|
||||
{
|
||||
IEnumerable<byte> GetValues()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
yield return 1;
|
||||
}
|
||||
}
|
||||
|
||||
Assert.ThrowsException<OverflowException>(() => GetValues().CountWhereNot(x => x % 2 == 0));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void DisposeAll_ShouldDispose_GivenCollection()
|
||||
{
|
||||
@ -36,6 +65,72 @@ public class EnumerableTests
|
||||
await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () => await collection!.DisposeAllAsync());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FirstWhereNot_ShouldReturnCorrectElements_GivenSequence()
|
||||
{
|
||||
var enumerable = new[] {2, 4, 6, 7, 8, 9, 10};
|
||||
int result = enumerable.FirstWhereNot(x => x % 2 == 0);
|
||||
Assert.AreEqual(7, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FirstWhereNot_ShouldThrowArgumentNullException_GivenNullSource()
|
||||
{
|
||||
Assert.ThrowsException<ArgumentNullException>(() => ((IEnumerable<int>?)null)!.FirstWhereNot(x => x % 2 == 0));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FirstWhereNot_ShouldThrowArgumentNullException_GivenNullPredicate()
|
||||
{
|
||||
Assert.ThrowsException<ArgumentNullException>(() => Array.Empty<int>().FirstWhereNotOrDefault(null!));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FirstWhereNot_ShouldThrowInvalidOperationException_GivenEmptySource()
|
||||
{
|
||||
Assert.ThrowsException<InvalidOperationException>(() => Array.Empty<int>().FirstWhereNot(x => x % 2 == 0));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FirstWhereNot_ShouldThrowInvalidOperationException_GivenSourceWithNoMatchingElements()
|
||||
{
|
||||
Assert.ThrowsException<InvalidOperationException>(() => 2.AsArrayValue().FirstWhereNot(x => x % 2 == 0));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FirstWhereNotOrDefault_ShouldReturnCorrectElements_GivenSequence()
|
||||
{
|
||||
var enumerable = new[] {2, 4, 6, 7, 8, 9, 10};
|
||||
int result = enumerable.FirstWhereNotOrDefault(x => x % 2 == 0);
|
||||
Assert.AreEqual(7, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FirstWhereNotOrDefault_ShouldThrowArgumentNullException_GivenNullSource()
|
||||
{
|
||||
Assert.ThrowsException<ArgumentNullException>(() => ((IEnumerable<int>?)null)!.FirstWhereNotOrDefault(x => x % 2 == 0));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FirstWhereNotOrDefault_ShouldThrowArgumentNullException_GivenNullPredicate()
|
||||
{
|
||||
Assert.ThrowsException<ArgumentNullException>(() => Array.Empty<int>().FirstWhereNotOrDefault(null!));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FirstWhereNotOrDefault_ShouldReturnDefault_GivenEmptySource()
|
||||
{
|
||||
int result = Array.Empty<int>().FirstWhereNotOrDefault(x => x % 2 == 0);
|
||||
Assert.AreEqual(default, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void FirstWhereNotOrDefault_ShouldReturnDefault_GivenSourceWithNoMatchingElements()
|
||||
{
|
||||
int result = 2.AsArrayValue().FirstWhereNotOrDefault(x => x % 2 == 0);
|
||||
Assert.AreEqual(default, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void For_ShouldTransform_GivenTransformationDelegate()
|
||||
{
|
||||
@ -94,6 +189,72 @@ public class EnumerableTests
|
||||
Assert.ThrowsException<ArgumentNullException>(() => source.ForEach(null!));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LastWhereNot_ShouldReturnCorrectElements_GivenSequence()
|
||||
{
|
||||
var enumerable = new[] {2, 4, 6, 7, 8, 9, 10};
|
||||
int result = enumerable.LastWhereNot(x => x % 2 == 0);
|
||||
Assert.AreEqual(9, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LastWhereNot_ShouldThrowArgumentNullException_GivenNullSource()
|
||||
{
|
||||
Assert.ThrowsException<ArgumentNullException>(() => ((IEnumerable<int>?)null)!.LastWhereNot(x => x % 2 == 0));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LastWhereNot_ShouldThrowArgumentNullException_GivenNullPredicate()
|
||||
{
|
||||
Assert.ThrowsException<ArgumentNullException>(() => Array.Empty<int>().LastWhereNot(null!));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LastWhereNot_ShouldThrowInvalidOperationException_GivenEmptySource()
|
||||
{
|
||||
Assert.ThrowsException<InvalidOperationException>(() => Array.Empty<int>().LastWhereNot(x => x % 2 == 0));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LastWhereNot_ShouldThrowInvalidOperationException_GivenSourceWithNoMatchingElements()
|
||||
{
|
||||
Assert.ThrowsException<InvalidOperationException>(() => 2.AsArrayValue().LastWhereNot(x => x % 2 == 0));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LastWhereNotOrDefault_ShouldReturnCorrectElements_GivenSequence()
|
||||
{
|
||||
var enumerable = new[] {2, 4, 6, 7, 8, 9, 10};
|
||||
int result = enumerable.LastWhereNotOrDefault(x => x % 2 == 0);
|
||||
Assert.AreEqual(9, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LastWhereNotOrDefault_ShouldThrowArgumentNullException_GivenNullSource()
|
||||
{
|
||||
Assert.ThrowsException<ArgumentNullException>(() => ((IEnumerable<int>?)null)!.LastWhereNotOrDefault(x => x % 2 == 0));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LastWhereNotOrDefault_ShouldThrowArgumentNullException_GivenNullPredicate()
|
||||
{
|
||||
Assert.ThrowsException<ArgumentNullException>(() => Array.Empty<int>().LastWhereNotOrDefault(null!));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LastWhereNotOrDefault_ShouldReturnDefault_GivenEmptySource()
|
||||
{
|
||||
int result = Array.Empty<int>().LastWhereNotOrDefault(x => x % 2 == 0);
|
||||
Assert.AreEqual(default, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void LastWhereNotOrDefault_ShouldReturnDefault_GivenSourceWithNoMatchingElements()
|
||||
{
|
||||
int result = 2.AsArrayValue().LastWhereNotOrDefault(x => x % 2 == 0);
|
||||
Assert.AreEqual(default, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Shuffled_ShouldThrow_GivenNull()
|
||||
{
|
||||
@ -112,6 +273,20 @@ public class EnumerableTests
|
||||
CollectionAssert.AreNotEqual(array, shuffled);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void WhereNot_ShouldReturnCorrectElements_GivenSequence()
|
||||
{
|
||||
var enumerable = new[] {2, 4, 6, 7, 8, 9, 10};
|
||||
IEnumerable<int> result = enumerable.WhereNot(x => x % 2 == 0);
|
||||
CollectionAssert.AreEqual(new[] {7, 9}, result.ToArray());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void WhereNot_ShouldThrowArgumentNullException_GivenNullSource()
|
||||
{
|
||||
Assert.ThrowsException<ArgumentNullException>(() => ((IEnumerable<int>?)null)!.WhereNot(x => x % 2 == 0));
|
||||
}
|
||||
|
||||
private class DummyClass
|
||||
{
|
||||
public int Value { get; set; }
|
||||
|
@ -7,6 +7,108 @@ namespace X10D.Collections;
|
||||
/// </summary>
|
||||
public static class EnumerableExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns a number that represents how many elements in the specified sequence do not satisfy a condition.
|
||||
/// </summary>
|
||||
/// <param name="source">A sequence that contains elements to be tested and counted.</param>
|
||||
/// <param name="predicate">A function to test each element for a condition.</param>
|
||||
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
|
||||
/// <returns>
|
||||
/// A number that represents how many elements in the sequence do not satisfy the condition in the
|
||||
/// <paramref name="predicate" /> function.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="source" /> or <paramref name="predicate" /> is null.</exception>
|
||||
/// <exception cref="OverflowException">
|
||||
/// The number of elements in <paramref name="source" /> is larger than <see cref="int.MaxValue" />.
|
||||
/// </exception>
|
||||
[Pure]
|
||||
public static int CountWhereNot<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
|
||||
{
|
||||
#if NET6_0
|
||||
ArgumentNullException.ThrowIfNull(source);
|
||||
ArgumentNullException.ThrowIfNull(predicate);
|
||||
#else
|
||||
if (source is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
}
|
||||
|
||||
if (predicate is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(predicate));
|
||||
}
|
||||
#endif
|
||||
|
||||
return source.Count(item => !predicate(item));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the first element in a sequence that does not satisfy a specified condition.
|
||||
/// </summary>
|
||||
/// <param name="source">An <see cref="IEnumerable{T}" /> to return an element from.</param>
|
||||
/// <param name="predicate">A function to test each element for a condition.</param>
|
||||
/// <typeparam name="TSource">The type of the elements in <paramref name="source" /></typeparam>
|
||||
/// <returns>The first element in the sequence that fails the test in the specified predicate function.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="source" /> or <paramref name="predicate" /> is null.</exception>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// <para>No element satisfies the condition in predicate.</para>
|
||||
/// -or-
|
||||
/// <para>The source sequence is empty.</para>
|
||||
/// </exception>
|
||||
[Pure]
|
||||
public static TSource FirstWhereNot<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
|
||||
{
|
||||
#if NET6_0
|
||||
ArgumentNullException.ThrowIfNull(source);
|
||||
ArgumentNullException.ThrowIfNull(predicate);
|
||||
#else
|
||||
if (source is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
}
|
||||
|
||||
if (predicate is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(predicate));
|
||||
}
|
||||
#endif
|
||||
|
||||
return source.First(item => !predicate(item));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the first element in a sequence that does not satisfy a specified condition.
|
||||
/// </summary>
|
||||
/// <param name="source">An <see cref="IEnumerable{T}" /> to return an element from.</param>
|
||||
/// <param name="predicate">A function to test each element for a condition.</param>
|
||||
/// <typeparam name="TSource">The type of the elements in <paramref name="source" /></typeparam>
|
||||
/// <returns>
|
||||
/// <see langword="default(TSource)" /> if <paramref name="source" /> is empty or if no element passes the test specified
|
||||
/// by <paramref name="predicate"/>; otherwise, the first element in <paramref name="source" /> that fails the test
|
||||
/// specified by <paramref name="predicate" />.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="source" /> or <paramref name="predicate" /> is null.</exception>
|
||||
[Pure]
|
||||
public static TSource? FirstWhereNotOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
|
||||
{
|
||||
#if NET6_0
|
||||
ArgumentNullException.ThrowIfNull(source);
|
||||
ArgumentNullException.ThrowIfNull(predicate);
|
||||
#else
|
||||
if (source is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
}
|
||||
|
||||
if (predicate is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(predicate));
|
||||
}
|
||||
#endif
|
||||
|
||||
return source.FirstOrDefault(item => !predicate(item));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs the specified action on each element of the <see cref="IEnumerable{T}" />.
|
||||
/// </summary>
|
||||
@ -128,6 +230,73 @@ public static class EnumerableExtensions
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the last element in a sequence that does not satisfy a specified condition.
|
||||
/// </summary>
|
||||
/// <param name="source">An <see cref="IEnumerable{T}" /> to return an element from.</param>
|
||||
/// <param name="predicate">A function to test each element for a condition.</param>
|
||||
/// <typeparam name="TSource">The type of the elements in <paramref name="source" /></typeparam>
|
||||
/// <returns>The last element in the sequence that fails the test in the specified predicate function.</returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="source" /> or <paramref name="predicate" /> is null.</exception>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// <para>No element satisfies the condition in predicate.</para>
|
||||
/// -or-
|
||||
/// <para>The source sequence is empty.</para>
|
||||
/// </exception>
|
||||
[Pure]
|
||||
public static TSource LastWhereNot<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
|
||||
{
|
||||
#if NET6_0
|
||||
ArgumentNullException.ThrowIfNull(source);
|
||||
ArgumentNullException.ThrowIfNull(predicate);
|
||||
#else
|
||||
if (source is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
}
|
||||
|
||||
if (predicate is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(predicate));
|
||||
}
|
||||
#endif
|
||||
|
||||
return source.Last(item => !predicate(item));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the last element in a sequence that does not satisfy a specified condition.
|
||||
/// </summary>
|
||||
/// <param name="source">An <see cref="IEnumerable{T}" /> to return an element from.</param>
|
||||
/// <param name="predicate">A function to test each element for a condition.</param>
|
||||
/// <typeparam name="TSource">The type of the elements in <paramref name="source" /></typeparam>
|
||||
/// <returns>
|
||||
/// <see langword="default(TSource)" /> if <paramref name="source" /> is empty or if no element passes the test specified
|
||||
/// by <paramref name="predicate"/>; otherwise, the last element in <paramref name="source" /> that fails the test
|
||||
/// specified by <paramref name="predicate" />.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="source" /> or <paramref name="predicate" /> is null.</exception>
|
||||
[Pure]
|
||||
public static TSource? LastWhereNotOrDefault<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
|
||||
{
|
||||
#if NET6_0
|
||||
ArgumentNullException.ThrowIfNull(source);
|
||||
ArgumentNullException.ThrowIfNull(predicate);
|
||||
#else
|
||||
if (source is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
}
|
||||
|
||||
if (predicate is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(predicate));
|
||||
}
|
||||
#endif
|
||||
|
||||
return source.LastOrDefault(item => !predicate(item));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reorganizes the elements in an enumerable by implementing a Fisher-Yates shuffle, and returns th shuffled result.
|
||||
/// </summary>
|
||||
@ -152,4 +321,35 @@ public static class EnumerableExtensions
|
||||
list.Shuffle(random);
|
||||
return list.AsReadOnly();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters a sequence of values based on a predicate, such that all elements in the result do not match the predicate.
|
||||
/// </summary>
|
||||
/// <param name="source">An <see cref="IEnumerable{T}" /> to filter.</param>
|
||||
/// <param name="predicate">A function to test each element for a condition.</param>
|
||||
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
|
||||
/// <returns>
|
||||
/// An <see cref="IEnumerable{T}" /> that contains elements from the input sequence that do not satisfy the condition.
|
||||
/// </returns>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="source" /> or <paramref name="predicate" /> is null.</exception>
|
||||
[Pure]
|
||||
public static IEnumerable<TSource> WhereNot<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
|
||||
{
|
||||
#if NET6_0
|
||||
ArgumentNullException.ThrowIfNull(source);
|
||||
ArgumentNullException.ThrowIfNull(predicate);
|
||||
#else
|
||||
if (source is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
}
|
||||
|
||||
if (predicate is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(predicate));
|
||||
}
|
||||
#endif
|
||||
|
||||
return source.Where(item => !predicate(item));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user