我有一个数字列表,我想选择一个特定大小的滑动窗口:
List<double> lst = {3,78,24,25,634,25,478,24};
int WindowSize = 4;
index = 0: return {3};
index = 1: return {3,78};
index = 2: return {3,78,24};
index = 3: return {3,78,24,25};
index = 4: return {78,24,25,634};
index = 5: return {24,25,634,25};
index = 6: return {25,634,25,478};
index = 7: return {634,25,478,24};
这不是一个很难的概念,但我正在尝试使用.Skip() .Take()
扩展方法来实现。 有没有更简单的方法可以在项目之前选择WindowSize
条目,而不是尝试查找起点,然后获取下一个WindowSize
条目? 我试图想出一种更简单的方法来使用 linq 执行此操作,而不是对 Skip()
和 Take()
进行所需的所有边界检查。
你可以反转列表,然后做一个 Count() - 索引,然后做一个 Take(),但这似乎效率不高。
我想这需要最少的边界检查 - 只是基本的健全性检查。看看这是否有效
IEnumerable<double> GetWindow(List<double> lst, int index, int windowSize) {
if(index >= lst.Length){
// Throw proper exception
}
return lst.Skip(index-windowSize).Take(Math.Min(index,windowSize));
}
如果您只想获得一个窗口,则您接受的答案看起来很合适。但是对于迭代多个窗口,我会选择这样的东西:
public static IEnumerable<IEnumerable<TSource>> Window<TSource>(
this IEnumerable<TSource> source, int size)
{
var q = new Queue<TSource>(size);
foreach (var value in source)
{
if (q.Count >= size)
q.Dequeue();
q.Enqueue(value);
yield return q;
}
}