Divide array into an array of subsequence array
This is quite cute:
static class ChunkExtension
{
public static IEnumerable<T[]> Chunkify<T>(
this IEnumerable<T> source, int size)
{
if (source == null) throw new ArgumentNullException("source");
if (size < 1) throw new ArgumentOutOfRangeException("size");
using (var iter = source.GetEnumerator())
{
while (iter.MoveNext())
{
var chunk = new T[size];
chunk[0] = iter.Current;
for (int i = 1; i < size && iter.MoveNext(); i++)
{
chunk[i] = iter.Current;
}
yield return chunk;
}
}
}
}
static class Program
{
static void Main(string[] args)
{
List<byte> bytes = new List<byte>() {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
var chunks = bytes.Chunkify(4);
foreach (byte[] chunk in chunks)
{
foreach (byte b in chunk) Console.Write(b.ToString("x2") + " ");
Console.WriteLine();
}
}
}
Voted answer works if you always get source.Length % size != 0
, though it is too verbose. Here goes a nicer implementation:
public static IEnumerable<T[]> AsChunks<T>(IEnumerable<T> source, int size)
{
var chunk = new T[size];
var i = 0;
foreach(var e in source)
{
chunk[i++] = e;
if (i==size)
{
yield return chunk;
i=0;
}
}
if (i>0) // Anything left?
{
Array.Resize(ref chunk, i);
yield return chunk;
}
}
void Main()
{
foreach(var chunk in AsChunks("Hello World!",5))
Console.WriteLine(new string(chunk));
}
Producing:
- Hello
- Worl
- d!
How about this:
var bytes = new List<byte>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
var result = Chunkify(bytes, 4);
IEnumerable<IEnumerable<T>> Chunkify<T>(IEnumerable<T> source, int chunkSize)
{
var indicies =
Enumerable.Range(0, source.Count()).Where(i => i%chunkSize==0);
var chunks =
indicies
.Select( i => source.Skip(i).Take(chunkSize) )
.Select( chunk => new { Chunk=chunk, Count=chunk.Count() } )
.Select( c => c.Count < chunkSize ? c.Chunk.Concat( Enumerable.Repeat( default(T), chunkSize - c.Count ) ) : c.Chunk )
;
return chunks;
}