csharp 对排序输入没有真正有效的LINQ GroupBy()实现

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了csharp 对排序输入没有真正有效的LINQ GroupBy()实现相关的知识,希望对你有一定的参考价值。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication4
{
    public class EnumeratorBox<T>
    {
        public IEnumerator<T> Value { get; set; }
        public bool IsCompleted { get; set; }

        public EnumeratorBox(IEnumerator<T> value)
        {
            Value = value;
        }
    }

    public class AdjacentGrouping<TKey, TElement> : IGrouping<TKey, TElement>
    {
        public TKey Key { get; private set; }

        private IEnumerator<TElement> enumerator;

        public AdjacentGrouping(TKey key, IEnumerator<TElement> enumerator)
        {
            this.Key = key;
            this.enumerator = enumerator;
        }

        public IEnumerator<TElement> GetEnumerator()
        {
            return enumerator;
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return enumerator;
        }
    }

    public struct GroupAdjacentByEnumerator<TElement, TKey> : IEnumerator<TElement>
    {
        private EnumeratorBox<TElement> enumeratorBox;
        private Func<TElement, TKey> keySelector;
        private TKey key;
        private bool started;

        public GroupAdjacentByEnumerator(EnumeratorBox<TElement> enumeratorBox, Func<TElement, TKey> keySelector, TKey key)
        {
            this.enumeratorBox = enumeratorBox;
            this.keySelector = keySelector;
            this.key = key;
            this.started = false;
        }

        public TElement Current
        {
            get { return enumeratorBox.Value.Current; }
        }

        public void Dispose()
        {
        }

        object System.Collections.IEnumerator.Current
        {
            get { return (enumeratorBox as System.Collections.IEnumerator).Current; }
        }

        public bool MoveNext()
        {
            if (!started)
            {
                started = true;
                return true;
            }

            if (!enumeratorBox.Value.MoveNext())
            {
                enumeratorBox.IsCompleted = true;
                return false;
            }

            var newKey = keySelector(enumeratorBox.Value.Current);
            return Object.Equals(newKey, key);
        }

        public void Reset()
        {
            throw new NotSupportedException();
        }
    }

    static class EnumerableExtensions
    {
        public static IEnumerable<IGrouping<TKey, TElement>> GroupAdjacentBy<TElement, TKey>(this IEnumerable<TElement> source, Func<TElement, TKey> keySelector)
        {
            var enumeratorBox = new EnumeratorBox<TElement>(source.GetEnumerator());

            if (!enumeratorBox.Value.MoveNext())
            {
                enumeratorBox.Value.Dispose();
                yield break;
            }

            do
            {
                var key = keySelector(enumeratorBox.Value.Current);
                yield return new AdjacentGrouping<TKey, TElement>(key, new GroupAdjacentByEnumerator<TElement, TKey>(enumeratorBox, keySelector, key));
            } while (!enumeratorBox.IsCompleted);

            enumeratorBox.Value.Dispose();
        }
    }

    class Program
    {
        static void Main()
        {
            var foo = new[] { 1, 1, 1, 2, 2, 3 };
            foreach (var group in foo.GroupAdjacentBy(x => x))
                Console.WriteLine("{0}: {1}", group.Key, String.Join(" ", group));
        }
    }
}

以上是关于csharp 对排序输入没有真正有效的LINQ GroupBy()实现的主要内容,如果未能解决你的问题,请参考以下文章

C#/Linq - 对字典进行排序

linq 按子字符串对数组中的字符串进行排序

使用 C# 、 LINQ 进行排序

能否用linq对数据库执行排序维护?

让我们一起写出更有效的CSharp代码吧,少年们!

CSharp使用另一个列表及其嵌套列表过滤带有LINQ查询的列表