Grouping consecutive identical items: IEnumerable to IEnumerable>

前端 未结 4 614
说谎
说谎 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:17

    Here's a solution that I think satisfies your requirements, works with any type of data item, and is quite short and readable:

    public static IEnumerable> Partition(this IEnumerable list)
    {
        var current = list.FirstOrDefault();
    
        while (!Equals(current, default(T))) {
            var cur = current;
            Func equalsCurrent = item => item.Equals(cur);
            yield return list.TakeWhile(equalsCurrent);
            list = list.SkipWhile(equalsCurrent);
            current = list.FirstOrDefault();
        }
    }
    

    Notes:

    1. Deferred execution is there (both TakeWhile and SkipWhile do it).
    2. I think this iterates over the entire collection only once (with SkipWhile); it does iterate over the collection once more when you process the returned IEnumerables, but the partitioning itself iterates only once.
    3. If you don't care about value types, you can add a constraint and change the while condition to a test for null.

    If I am somehow mistaken, I 'd be especially interested in comments pointing out the mistakes!

    Very Important Aside:

    This solution will not allow you to enumerate the produced enumerables in any order other than the one it provides them in. However, I think the original poster has been pretty clear in comments that this is not a problem.

提交回复
热议问题