LINQ: Group a list of strings into chunks, dividing the chunks by a whole-line marker (in the example "<Custom>"
)
public static partial class Queries
{
public static IEnumerable<string[]> Execute(
this IQueryHandler<DataChunker, IEnumerable<string[]>> handler,
IEnumerable<string> data)
{
return handler.Execute(new DataChunker(data));
}
public class DataChunker : IQuery<IEnumerable<string[]>>
{
public DataChunker(IEnumerable<string> data)
{
this.Data = data;
}
public IEnumerable<string> Data { get; set; }
}
public static partial class Handlers
{
public sealed class CustomDataChunkerHandler :
IQueryHandler<DataChunker, IEnumerable<string[]>>
{
public const string LineBreak = "<Custom>";
public IEnumerable<string[]> Execute(DataChunker query)
{
var enumerator = query.Data.GetEnumerator();
while (enumerator.MoveNext())
{
yield return NextChunk(enumerator).ToArray();
}
}
private static IEnumerable<string> NextChunk(IEnumerator<string> enumerator)
{
do
{
yield return enumerator.Current;
}
while (enumerator.MoveNext() && enumerator.Current != LineBreak);
}
}
}
}
public class CustomDataChunkerHandlerTests
{
[TestCase]
public void Execute_WithNoData_ReturnsNothing()
{
var handler = new Queries.Handlers.CustomDataChunkerHandler();
var result = handler.Execute(NoData)
.ToArray();
result.Length.Should().Be(0);
}
[TestCase]
public void Execute_WithOneRowOfData_ReturnsOneRowOfData()
{
var handler = new Queries.Handlers.DepConDataChunkerHandler();
var result = handler.Execute(OneRowOfData)
.ToArray();
result[0].Should().BeEquivalentTo("a");
}
[TestCase]
public void Execute_WithOneChunkOfData_ReturnsOneRowOfData()
{
var handler = new Queries.Handlers.CustomDataChunkerHandler();
var result = handler.Execute(OneChunkOfData)
.ToArray();
result[0].Should().BeEquivalentTo(new string[3] { "b", "c", "d" });
}
[TestCase]
public void Execute_WithLotsOfData_ReturnsChunkedData()
{
var handler = new Queries.Handlers.CustomDataChunkerHandler();
var result = handler.Execute(LotsOfData)
.ToArray();
result[0].Should().BeEquivalentTo(new string[3] { "f", "g", "h" });
result[1].Should().BeEquivalentTo(new string[3] { "i", "j", "k" });
}
private static IEnumerable<string> NoData
{
get
{
return Enumerable.Empty<string>();
}
}
private static IEnumerable<string> OneRowOfData
{
get
{
yield return "a";
}
}
private static IEnumerable<string> OneChunkOfData
{
get
{
yield return "b";
yield return "c";
yield return "d";
}
}
private static IEnumerable<string> LotsOfData
{
get
{
yield return "f";
yield return "g";
yield return "h";
yield return Queries.Handlers.CustomDataChunkerHandler.LineBreak;
yield return "i";
yield return "j";
yield return "k";
yield return Queries.Handlers.CustomDataChunkerHandler.LineBreak;
}
}
}