When working with collections in C#, you may need to process elements in fixed-size, overlapping groups — often referred to as a “sliding window.” This technique is particularly useful when analyzing sequential data, such as numerical series, text processing, and pattern recognition.
Here, we’ll implement a reusable extension method that efficiently generates sliding windows from a list using LINQ.
The Problem
Given a list of elements, we want to generate a sequence of sublists, where each sublist consists of consecutive elements of a fixed size. For example, with the list {1, 2, 3, 4, 5}
and a window size of 2
, the expected output would be:
{ {1,2}, {2,3}, {3,4}, {4,5} }
Only fully populated windows are included. If the list does not contain enough elements to form a complete window at the end, those elements are excluded.
Implementation
Here’s the generic extension method for List<T>
:
/// <summary>
/// Generates a sequence of contiguous sublists (sliding windows) of a fixed size from the source list.
/// Only fully populated windows are returned. If the list contains elements that do not form a complete
/// window at the end, those elements are omitted.
/// </summary>
/// <typeparam name="T">The type of the elements in the list.</typeparam>
/// <param name="list">The source list from which to generate windows.</param>
/// <param name="size">The fixed size of each window.</param>
/// <returns>
/// A list of windows, where each window is represented as a sublist of <typeparamref name="T"/>.
/// If the list has fewer elements than the window size, an empty list is returned.
/// </returns>
public static List<List<T>> Window<T>(this List<T> list, int size)
{
var windowed = new List<List<T>>();
for (var i = 0; i <= list.Count - size; i++)
{
windowed.Add(list.Skip(i).Take(size).ToList());
}
return windowed;
}
Breaking Down the Code
Method Signature
This is an extension method for List<T>
, allowing direct invocation on any list.
Iterating Through the List
A for
loop runs from i = 0
to i = list.Count - size
, ensuring that only complete windows are included. If not enough elements remain, the iteration stops.
Generating Each Window
The combination of Skip(i)
and Take(size)
extracts a sublist starting at index i
with the specified size. Converting it to a list ensures the extracted elements are stored separately before adding them to the final collection.
Handling Edge Cases
If the input list contains fewer elements than size
, an empty list is returned instead of producing incomplete windows.
Where This Can Be Applied
This sliding window method is useful in various scenarios, including:
- Data Processing: Splitting sequential datasets into structured segments for numerical analysis.
- String Manipulation: Extracting overlapping sequences of characters or words for text processing.
- Pattern Recognition: Detecting trends in sequential data, such as event logs or sensor readings.
Final Thoughts
Encapsulating the sliding window logic in an extension method improves code reusability and clarity. By leveraging LINQ, this approach provides a concise and efficient way to process sequential data structures. The method can be easily modified to accommodate different collection types or specialized windowing requirements.