列表视图滑动窗口

本文关键字:窗口 视图 列表 | 更新日期: 2023-09-27 17:56:23

我有一个数字列表,我想选择一个特定大小的滑动窗口:

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;
    }
}