I\'ve got an interresting problem: Given an IEnumerable
, is it possible to yield a sequence of IEnumerable
Is this what you are looking for?
This solution relies on object state because it's difficult to share state between two IEnumerable methods that use yield (no ref or out params).
internal class Program
{
static void Main(string[] args)
{
var result = new[] { "a", "b", "b", "b", "c", "c", "d" }.Partition();
foreach (var r in result)
{
Console.WriteLine("Group".PadRight(16, '='));
foreach (var s in r)
Console.WriteLine(s);
}
}
}
internal static class PartitionExtension
{
public static IEnumerable> Partition(this IEnumerable src)
{
var grouper = new DuplicateGrouper();
return grouper.GroupByDuplicate(src);
}
}
internal class DuplicateGrouper
{
T CurrentKey;
IEnumerator Itr;
bool More;
public IEnumerable> GroupByDuplicate(IEnumerable src)
{
using(Itr = src.GetEnumerator())
{
More = Itr.MoveNext();
while (More)
yield return GetDuplicates();
}
}
IEnumerable GetDuplicates()
{
CurrentKey = Itr.Current;
while (More && CurrentKey.Equals(Itr.Current))
{
yield return Itr.Current;
More = Itr.MoveNext();
}
}
}
Edit: Added extension method for cleaner usage. Fixed loop test logic so that "More" is evaluated first.
Edit: Dispose the enumerator when finished