2017-01-06 4 views
3

Ich suchte nach einer "Fenster" -Funktion wie F # 's Seq.windowed oder die Reaktive Erweiterungen Window. Es sieht so aus, als ob es von Leuten wie Select-Object (die bereits die Take/Skip-Funktionalität haben) bereitgestellt wird, aber das ist es nicht.Hat PowerShell eine "Fenster" -Funktion?

Wenn nichts verfügbar ist, irgendwelche Ideen zur Implementierung von "Fenster" ohne unnötige prozedurale Schleife?

Ich suche nach etwas, das gut mit der PowerShell-Pipeline funktioniert.

+0

Nicht etwas in PowerShell verfügbar, aber [dies könnte nützlich sein] (http://stackoverflow.com/questions/38566936/how-can-i-calculate-a-sliding-window-over-an- Array-in-Powershell)? Was meinst du mit "arbeitet gut mit der PowerShell-Pipeline"? Kannst du zeigen/beschreiben, welches Verhalten du bei einer Sample-Eingabe/Ausgabe erwartest? –

+0

'Funktionsfenster {param ($ size) begin {$ array = [Objekt []] :: new ($ size); $ i = 0} Prozess {if ($ i -lt $ size) {$ array [$ i ++] = $ _; if ($ i -eq $ size) {, @ ($ array)}} else {, @ (($ array = @ ($ array | select -skip 1;, $ _)))}}} ' – PetSerAl

Antwort

3

Sie verwenden müssen, um eine Art Warteschlange genug vorherige Pipeline Elemente zu sammeln und zu drehen:

0..($a.Length-$w) | ForEach-Object -Begin { 
    $myWindows = @() 
} -Process { 
    $myWindows += @(,$a[$_..($_+$w-1)]) 
} 

die Sie dann wie verwenden:

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

Und Sie können es wie folgt verwenden:

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

Ordentlich. ('$ Queue = New-Object -TypeName" Collections.Queue "$ Size' für jeden, der PSv4 benutzt) – TessellatingHeckler

+0

Liebe das! Gut gemacht. – briantist

+0

Benötige ich unbedingt eine Warteschlange? Was ist mit einem lokalen Array, dem ich hinzufüge, überprüfe Count und setze es zurück? Irgendwelche Einschränkungen dort? –

1

Es gibt keinen solchen eingebauten so weit ich weiß. Powershell Handhabung der Pipeline und insbesondere seine starken Beharren auf Abrollen enumerables macht es ein bisschen schwierig, die Lage sein, nur eine Funktion Rohr schreibt in, sondern als allgemeinen Ausdruck:

$a = 1..10 # an array contain 1 through 10 
$w = 4  # window size of 4 

0..($a.Length-$w) | ForEach-Object -Process { 
    $a[$_..($_+$w-1)] 
} 

Das macht Prozessanordnungen, die das Fenster, das du willst. Es ist einfacher, so zu sehen:

0..($a.Length-$w) | ForEach-Object -Process { 
    "This is my window: $($a[$_..($_+$w-1)])" 
} 

Die Sache ist, wenn man versucht, die über diese Art und Weise zu tun:

0..($a.Length-$w) | ForEach-Object -Process { 
    $a[$_..($_+$w-1)] 
} | ForEach-Object -Process { 
    "This is my window: $_" 
} 

Sie sehr enttäuscht sein würde als der „Fenster“ Array abgerollt wurde vor in ForEach-Object geleitet werden; ein Problem, das Sie mit irgendeiner Pipeline-Funktion haben, die Sie geschrieben haben, um das auch zu handhaben.

Es gibt keine Möglichkeit für sie innerhalb der Funktion zu kompensieren, müssten Sie dafür Sorge tragen, weil auch auf Zuweisung innerhalb des ForEach-Object Block zu verwenden:

$myWindows = 0..($a.Length-$w) | ForEach-Object -Process { 
    $a[$_..($_+$w-1)] 
} 

Es abgerollt werden würde.

Also dann müssen Sie so etwas wie:

$myWindows | ForEach-Object -Process { 
    "This is my window: $_" 
} 
+0

* Da ist keine Möglichkeit, es innerhalb der Funktion zu kompensieren * Wirklich? Funktioniert das nicht für Sie? '$ MyWindows = @ (0 .. ($ a.Length- $ w) |% {, $ a [$ _ .. ($ _ + $ w-1)]})'? – PetSerAl

+0

@PetSerAl Ich habe das als Beispiel (zweite der letzte Codeblock). Was ich meine ist, dass, wenn Sie in der Lage sein würden, ein vorhandenes Array in etwas zu pipettieren und ein Fenster zu bearbeiten (wie $ a | Select-Window), können Sie nicht, weil die Funktion ein einzelnes Element nach dem anderen erhalten wird kann nicht auf die anderen Array-Elemente zugreifen.Der Aufrufer muss kompensieren: ', $ a | Select-Fenster'. – briantist

+1

'0 .. ($ a.Länge- $ w) | % {, $ a [$ _ .. ($ _ + $ w-1)]} | % {"Einzelarray zur Zeit: $ _"} ' – PetSerAl

Verwandte Themen