Skip to content

Instantly share code, notes, and snippets.

@jbogard
Last active December 15, 2015 05:19
Show Gist options
  • Save jbogard/5207998 to your computer and use it in GitHub Desktop.
Save jbogard/5207998 to your computer and use it in GitHub Desktop.
Slice and dice baby
public static IEnumerable<IEnumerable<TSource>> Slice<TSource>(
this IEnumerable<TSource> sequence,
int maxItemsPerSlice)
{
if (maxItemsPerSlice <= 0)
{
throw new ArgumentOutOfRangeException("maxItemsPerSlice", "maxItemsPerSlice must be greater than 0");
}
var slice = new List<TSource>(maxItemsPerSlice);
foreach (var item in sequence)
{
slice.Add(item);
if (slice.Count == maxItemsPerSlice)
{
yield return slice.ToArray();
slice = new List<TSource>(maxItemsPerSlice);
}
}
// return the "crumbs" that
// didn't make it into a full slice
if (slice.Count > 0)
{
yield return slice.ToArray();
}
}
public static IEnumerable<IEnumerable<TResult>> Slice<TSource, TResult>(
this IEnumerable<TSource> sequence,
int maxItemsPerSlice,
Func<TSource, TResult> selector)
{
if (maxItemsPerSlice <= 0)
{
throw new ArgumentOutOfRangeException("maxItemsPerSlice", "maxItemsPerSlice must be greater than 0");
}
var slice = new List<TResult>(maxItemsPerSlice);
foreach (var item in sequence)
{
slice.Add(selector(item));
if (slice.Count == maxItemsPerSlice)
{
yield return slice.ToArray();
slice.Clear();
}
}
// return the "crumbs" that
// didn't make it into a full slice
if (slice.Count > 0)
{
yield return slice.ToArray();
}
}
@pedroreys
Copy link

Hey Jimmy, Michael found a bug in this Slice extension method.

Here is a test that reproduces the issue:

public void Should_slice_collection_without_side_effects()
{
    var list = new List<IEnumerable<int>>();

     var otherList = Enumerable.Range(0, 9);

     var result = otherList.Slice(3);

     list.AddRange(result);

     list.Count().ShouldEqual(3);

     var firstSlice = list[0];

     //This will fail, firstSlice will be an empty array
     firstSlice.ToArray().ShouldEqual(new[] { 0, 1, 2 });
 }

To fix it, create a new List instance and assign it to slice instead of calling slice.Clear();

@jbogard
Copy link
Author

jbogard commented May 2, 2013

HAPPY NOW?!?

@pedroreys
Copy link

👍

@pedroreys
Copy link

oops, spoke too soon, line 50 is still broken

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment