c# MoreLinq 之 Window
2021-02-21 本文已影响0人
wwmin_
前言
本系列是对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
关于博主:评论和私信会在第一时间回复。或者[直接私信]我。
版权声明:转载请注明出处!
声援博主:如果您觉得文章对您有帮助,关注点赞, 您的鼓励是博主的最大动力!