// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT License.
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
namespace System.Linq
{
public static partial class EnumerableEx
{
///
/// Generates a sequence of non-overlapping adjacent buffers over the source sequence.
///
/// Source sequence element type.
/// Source sequence.
/// Number of elements for allocated buffers.
/// Sequence of buffers containing source sequence elements.
public static IEnumerable> Buffer(this IEnumerable source, int count)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (count <= 0)
throw new ArgumentOutOfRangeException(nameof(count));
return BufferCore(source, count, count);
}
///
/// Generates a sequence of buffers over the source sequence, with specified length and possible overlap.
///
/// Source sequence element type.
/// Source sequence.
/// Number of elements for allocated buffers.
/// Number of elements to skip between the start of consecutive buffers.
/// Sequence of buffers containing source sequence elements.
public static IEnumerable> Buffer(this IEnumerable source, int count, int skip)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (count <= 0)
throw new ArgumentOutOfRangeException(nameof(count));
if (skip <= 0)
throw new ArgumentOutOfRangeException(nameof(skip));
return BufferCore(source, count, skip);
}
private static IEnumerable> BufferCore(IEnumerable source, int count, int skip)
{
var buffers = new Queue>();
var i = 0;
foreach (var item in source)
{
if (i % skip == 0)
{
buffers.Enqueue(new List(count));
}
foreach (var buffer in buffers)
{
buffer.Add(item);
}
if (buffers.Count > 0 && buffers.Peek().Count == count)
{
yield return buffers.Dequeue();
}
i++;
}
while (buffers.Count > 0)
{
yield return buffers.Dequeue();
}
}
}
}