// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; 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 source.Buffer_(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 source.Buffer_(count, skip); } private static IEnumerable> Buffer_(this 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(); } } /// /// Represents a buffer exposing a shared view over an underlying enumerable sequence. /// /// Element type. public interface IBuffer : IEnumerable, IDisposable { } }