Grouping consecutive identical items: IEnumerable to IEnumerable>

前端 未结 4 613
说谎
说谎 2021-02-09 09:38

I\'ve got an interresting problem: Given an IEnumerable, is it possible to yield a sequence of IEnumerable>

4条回答
  •  借酒劲吻你
    2021-02-09 10:22

    Is this what you are looking for?

    • Iterate list only once.
    • Defer execution.
    • No intermediate collections (my other post failed on this criterion).

    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

提交回复
热议问题