美文网首页
c# MoreLinq 之 Window

c# MoreLinq 之 Window

作者: wwmin_ | 来源:发表于2021-02-21 23:24 被阅读0次

    前言

    本系列是对MoreLinq库的学习与总结,分析各个Api的实现方式及用法,也为能写出更高效的Linq打下基础。

    window 依据个数依次返回指定大小窗口数据

    //window 一次选取若干个相同数量且连续的数据, 
    //如同使用带有窗口的卡尺一次移动一个位置看到的连续数据的效果
    void WindowFunc()
    {
        var a = new List<int> { 1, 2, 3, 4, 5 };
        foreach (var t in a.Window(4))
        {
            var s = string.Join(',', t);
            s.Dump();
        }
    }
    

    结果是:

    1,2,3,4
    2,3,4,5
    

    Window定义:

    public static class MoreEnumerable
    {
            /// <summary>
            /// Processes a sequence into a series of subsequences representing a windowed subset of the original
            /// </summary>
            /// <remarks>
            /// The number of sequences returned is: <c>Max(0, sequence.Count() - windowSize) + 1</c><br/>
            /// Returned subsequences are buffered, but the overall operation is streamed.<br/>
            /// </remarks>
            /// <typeparam name="TSource">The type of the elements of the source sequence</typeparam>
            /// <param name="source">The sequence to evaluate a sliding window over</param>
            /// <param name="size">The size (number of elements) in each window</param>
            /// <returns>A series of sequences representing each sliding window subsequence</returns>
        public static IEnumerable<IList<TSource>> Window<TSource>(this IEnumerable<TSource> source, int size)
        {
            if (source == null) throw new ArgumentNullException(nameof(source));
            if (size <= 0) throw new ArgumentOutOfRangeException(nameof(size));
            return _();
            IEnumerable<IList<TSource>> _()
            {
                using var iter = source.GetEnumerator();
                var window = new TSource[size];
                int i;
                for (i = 0; i < size && iter.MoveNext(); i++)
                {
                    window[i] = iter.Current;
                }
                if (i < size)
                    yield break;
    
                while (iter.MoveNext())
                {
                    var newWindow = new TSource[size];
                    Array.Copy(window, 1, newWindow, 0, size - 1);
                    newWindow[size - 1] = iter.Current;
    
                    yield return window;
                    window = newWindow;
                }
                yield return window;
    
            }
        }
    }
    

    分析:
    首先遍历指定大小的数据形成第一条window,此时没有返回数据直接遍历下一条window,形成之后便返回第一条window,继续遍历则重复上一个操作的流程,直到数据结尾。
    在形成window时使用了Array.Copy(oldArray,oldArrayStartIndex,newArray,newArrayStartIndex,newArrayEndIndex)方法。
    并且整个实现使用了yield返回迭代对象的方法。

    本文作者:wwmin
    微信公众号: DotNet技术说
    本文链接:https://www.jianshu.com/p/71ae431921b8
    关于博主:评论和私信会在第一时间回复。或者[直接私信]我。
    版权声明:转载请注明出处!
    声援博主:如果您觉得文章对您有帮助,关注点赞, 您的鼓励是博主的最大动力!

    相关文章

      网友评论

          本文标题:c# MoreLinq 之 Window

          本文链接:https://www.haomeiwen.com/subject/jtvcfltx.html