Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add CountIsExactly.

  • Loading branch information...
commit 4d7110c836ba88b487179f64f04c1311bc3567ae 1 parent 1873494
@bgrainger bgrainger authored
View
38 src/Logos.Utility/EnumerableUtility.cs
@@ -11,6 +11,44 @@ namespace Logos.Utility
public static class EnumerableUtility
{
/// <summary>
+ /// Returns true if the count is as specified.
+ /// </summary>
+ /// <typeparam name="T">The type of the element.</typeparam>
+ /// <param name="source">The sequence.</param>
+ /// <param name="count">The count.</param>
+ /// <returns>True if the count is as specified.</returns>
+ /// <remarks>This method will often be faster than calling Enumerable.Count() and testing that value
+ /// when the count may be much larger than the count being tested.</remarks>
+ public static bool CountIsExactly<T>(this IEnumerable<T> source, int count)
+ {
+ if (source == null)
+ throw new ArgumentNullException("source");
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count");
+
+ ICollection<T> collection = source as ICollection<T>;
+ if (collection != null)
+ {
+ // use ICollection<T>.Count if available
+ return collection.Count == count;
+ }
+ else
+ {
+ // iterate the sequence
+ using (IEnumerator<T> it = source.GetEnumerator())
+ {
+ while (it.MoveNext())
+ {
+ if (count == 0)
+ return false;
+ count--;
+ }
+ return count == 0;
+ }
+ }
+ }
+
+ /// <summary>
/// Returns the source sequence, or an empty sequence if <paramref name="source"/> is <c>null</c>.
/// </summary>
/// <param name="source">The source sequence.</param>
View
28 tests/Logos.Utility.Tests/EnumerableUtilityTests.cs
@@ -1,5 +1,4 @@
-
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
@@ -9,6 +8,31 @@ namespace Logos.Utility.Tests
[TestFixture]
public class EnumerableUtilityTests
{
+ [TestCase(new int[0], 0, true)]
+ [TestCase(new int[0], 1, false)]
+ [TestCase(new[] { 1 }, 0, false)]
+ [TestCase(new[] { 1 }, 1, true)]
+ [TestCase(new[] { 1 }, 2, false)]
+ [TestCase(new[] { 1 }, int.MaxValue, false)]
+ public void CountIsExactly(int[] items, int count, bool expected)
+ {
+ Assert.AreEqual(expected, items.CountIsExactly(count));
+ Assert.AreEqual(expected, YieldIntegers(items.Length).CountIsExactly(count));
+ }
+
+ private static IEnumerable<int> YieldIntegers(int count)
+ {
+ for (int i = 0; i < count; i++)
+ yield return i;
+ }
+
+ [Test]
+ public void CountIsExactlyInvalidArguments()
+ {
+ Assert.Throws<ArgumentOutOfRangeException>(() => new int[0].CountIsExactly(-1));
+ Assert.Throws<ArgumentNullException>(() => EnumerableUtility.CountIsExactly(default(int[]), -1));
+ }
+
[Test]
public void EmptyIfNullNull()
{
Please sign in to comment.
Something went wrong with that request. Please try again.