Skip to content

Commit

Permalink
chore: rename PartitionExtensions to ChunkExtensions. Remove the Chun…
Browse files Browse the repository at this point in the history
…k extension on .NET 6 since it has a built-in method that provides the same behavior.
  • Loading branch information
skwasjer committed Dec 31, 2021
1 parent 1c36be4 commit 57e4385
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 34 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v5.3.3

- Use new `Chunk()` LINQ API for .NET 6 and change own `Partition()` method into polyfill for older framework targets.

## v5.3.2

- Change `master` branch to `main`, requiring update to CI scripts, and update all external page references.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,55 @@
namespace IbanNet.Extensions
{
[DebuggerStepThrough]
internal static class PartitionExtensions
internal static class ChunkExtensions
{
#if !NET6_0_OR_GREATER
/// <summary>
/// Splits a given <paramref name="sequence" /> into partitions of specified <paramref name="size" />.
/// Split the elements of a sequence into chunks of size at most <paramref name="size"/>.
/// </summary>
/// <remarks>
/// If the number of elements in the <paramref name="sequence" /> is not an exact multiple of <paramref name="size" />, the last partition of the returned partition set is smaller.
/// Every chunk except the last will be of size <paramref name="size"/>.
/// The last chunk will contain the remaining elements and may be of a smaller size.
/// </remarks>
/// <typeparam name="TSource">The type of the sequence elements.</typeparam>
/// <param name="sequence">The sequence to partition.</param>
/// <param name="size">The size of each partition to split the <paramref name="sequence" /> into.</param>
/// <returns>an enumerable of partitions</returns>
public static IEnumerable<IEnumerable<TSource>> Partition<TSource>(this IEnumerable<TSource> sequence, int size)
/// <typeparam name="TSource">The type of the source elements.</typeparam>
/// <param name="source">The source sequence.</param>
/// <param name="size">The size of each chunk to split the <paramref name="source" /> into.</param>
/// <returns>an enumerable of chunks</returns>
public static IEnumerable<IEnumerable<TSource>> Chunk<TSource>(this IEnumerable<TSource> source, int size)
{
if (sequence is null)
if (source is null)
{
throw new ArgumentNullException(nameof(sequence));
throw new ArgumentNullException(nameof(source));
}

if (size <= 0)
{
throw new ArgumentOutOfRangeException(nameof(size));
}

return PartitionIterator(sequence, size);
return ChunkIterator(source, size);
}

private static IEnumerable<IEnumerable<TSource>> PartitionIterator<TSource>(this IEnumerable<TSource> sequence, int size)
private static IEnumerable<IEnumerable<TSource>> ChunkIterator<TSource>(this IEnumerable<TSource> source, int size)
{
var partition = new List<TSource>(size);
foreach (TSource item in sequence)
var chunks = new List<TSource>(size);
foreach (TSource item in source)
{
partition.Add(item);
if (partition.Count == size)
chunks.Add(item);
if (chunks.Count == size)
{
yield return partition;
yield return chunks;

partition = new List<TSource>(size);
chunks = new List<TSource>(size);
}
}

if (partition.Count > 0)
if (chunks.Count > 0)
{
yield return partition;
yield return chunks;
}
}
#endif

/// <summary>
/// Splits a given <paramref name="sequence" /> into partitions when encountering any of the <paramref name="chars" />.
Expand Down
2 changes: 1 addition & 1 deletion src/IbanNet/Iban.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public string ToString(IbanFormat format)
#endif
IbanFormat.Print => string.Join(" ",
_iban
.Partition(segmentSize)
.Chunk(segmentSize)
.Select(p => new string(p.ToArray()))
),
// TODO: change to IbanFormatException in future major release.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
namespace IbanNet.Extensions
{
public class PartitionExtensionTests
public class ChunkExtensionsTests
{
[Fact]
public void Given_null_collection_when_partitioning_it_should_throw()
public void Given_null_collection_when_chunking_it_should_throw()
{
IEnumerable<object> sequence = null;
IEnumerable<object> source = null;

// Act
// ReSharper disable once AssignNullToNotNullAttribute
Action act = () => sequence.Partition(2);
Action act = () => source.Chunk(2);

// Assert
act.Should()
.Throw<ArgumentNullException>()
.Which.ParamName.Should()
.Be(nameof(sequence));
.Be(nameof(source));
}

[Theory]
[InlineData(0)]
[InlineData(-1)]
[InlineData(int.MinValue)]
public void Given_invalid_size_when_partitioning_it_should_throw(int size)
public void Given_invalid_size_when_chunking_it_should_throw(int size)
{
IEnumerable<object> sequence = new List<object>();
IEnumerable<object> source = new List<object>();

// Act
Action act = () => sequence.Partition(size);
Action act = () => source.Chunk(size);

// Assert
act.Should()
Expand All @@ -40,18 +40,18 @@ public void Given_invalid_size_when_partitioning_it_should_throw(int size)
[InlineData(1, 50, 1)]
[InlineData(3, 17, 2)]
[InlineData(9, 6, 5)]
public void Given_collection_when_partitioning_it_should_return_correct_partitioned_enumerable(int size, int expectedPartitions, int expectedLastPartitionSize)
public void Given_collection_when_chunking_it_should_return_expected_chunks(int size, int expectedPartitions, int expectedLastPartitionSize)
{
IEnumerable<int> sequence = Enumerable.Range(0, 50).Select((_, i) => i).ToList();
IEnumerable<int> source = Enumerable.Range(0, 50).Select((_, i) => i).ToList();

// Act
var actual = sequence.Partition(size).ToList();
var actual = source.Chunk(size).ToList();

// Assert
actual.Should().HaveCount(expectedPartitions);
actual.Take(actual.Count - 1).Should().OnlyContain(inner => inner.Count() == size, "all but the last should at least be of the requested size");
actual.Last().Should().HaveCount(expectedLastPartitionSize, "the last partition can be less than or equal to the requested size");
actual.SelectMany(i => i).Should().BeEquivalentTo(sequence, opts => opts.WithStrictOrdering(), "joined back together it should be same as original sequence");
actual.SelectMany(i => i).Should().BeEquivalentTo(source, opts => opts.WithStrictOrdering(), "joined back together it should be same as original source");
}

[Fact]
Expand Down Expand Up @@ -116,7 +116,7 @@ public void Given_that_when_is_null_when_partitioning_it_should_throw()
#if USE_SPANS
ReadOnlySpan<char> sequence = string.Empty;
#else
string sequence = string.Empty;
string sequence = string.Empty;
#endif
sequence.PartitionOn(when);
};
Expand Down

0 comments on commit 57e4385

Please sign in to comment.