Search code examples
powershellfunctional-programmingpipeline

Does PowerShell have a "window" function?


I was looking for a "window" function like F#'s Seq.windowed or the Reactive extensions Window. It looks like it would be provided by the likes of Select-Object (which already has take / skip functionality), but it is not.

If nothing is readily available, any ideas on implementing "window" without unnecessary procedural looping?

I'm looking for something that works with the PowerShell pipeline nicely.


Solution

  • You need to use some kind of queue to accumulate and rotate enough previous pipeline items:

    function Window {
        param($Size)
        begin {
            $Queue = [Collections.Queue]::new($Size)
        }
        process {
            $Queue.Enqueue($_)
            if($Queue.Count -eq $Size) {
                @(
                    ,$Queue.ToArray()
                    [void]$Queue.Dequeue()
                )
            }
        }
    }
    

    And you can use it like this:

    1..10 | Window 4 | Window 3 | Format-Custom -Expand CoreOnly