2017-01-06 3 views
3

F #의 Seq.windowed 또는 반응 확장 Window과 같은 "창"기능을 찾고있었습니다. Select-Object (이미 take/skip 기능이 있음) 등이 제공하는 것처럼 보이지만 그렇지 않습니다.PowerShell에는 "창"기능이 있습니까?

아무 것도 사용할 수 없다면 불필요한 절차 루핑없이 "창"을 구현하는 아이디어가 있습니까?

저는 PowerShell 파이프 라인과 잘 작동하는 것을 찾고 있습니다.

+0

PowerShell에서 쉽게 사용할 수있는 것은 없지만 [유용 할 수 있습니다.] (http://stackoverflow.com/questions/38566936/how-can-i-calculate-a-sliding-window-over-an- array-in-powershell)? 또한 "PowerShell 파이프 라인과 함께 잘 작동합니다"라는 것은 무엇을 의미합니까? 샘플 입출력으로 어떤 종류의 동작을 기대할 수 있습니까? –

+0

'function window {param ($ size) begin {$ array = [object []] :: new ($ size); $ i = 0} 프로세스 {if ($ i -lt $ size) {$ array [$ i ++] = $ _; (배열 $ {$ array $}))}}}' – PetSerAl

답변

3

:처럼 당신이 후 사용할 수

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

:

그래서 당신은 뭔가를해야합니다 :

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

그리고 다음과 같이 사용할 수 있습니다.

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

깔끔함. ('$ Queue = New-Object -TypeName "Collections.Queue"PSv4를 사용하는 다른 사람들을위한 $ Size ") – TessellatingHeckler

+0

Love this! 잘 했어. – briantist

+0

엄격하게 대기열이 필요합니까? 내가 추가하고 Count를 확인하고 재설정 한 로컬 배열은 어떻습니까? 거기에 어떤 한계가 있니? –

1

내가 아는 한 그런 내장은 없습니다. 줄이기 enumerables에 강한 주장 파이프 라인의 특히 PowerShell에서의 처리는 조금 어려운 단지로 파이프 기능을 쓸 수있게하지만, 일반적인 표현으로 :

$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)] 
} 

있는 프로세스 배열을 않는 네가 원하는 창. 다음과 같이보고 쉽게 :

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

것은, 당신은이 방법으로 위의 작업을 수행하려고하는 경우 : 당신은 "창"배열하기 전에 풀려되면서 매우 실망 것

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

ForEach-Object; 이것을 처리하기 위해 작성한 파이프 라인 기능에 문제가있을 수 있습니다.

함수 내에서 보상 할 수있는 방법이 없습니다, 당신은 때문에도 할당에 ForEach-Object 블록 내부에 사용하는데주의를 기울여야 할 것 :

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

이 그것은

를 언 롤링 할 것입니다. 당신은 축적 큐의 어떤 종류를 사용할 필요가 충분한 이전 파이프 라인 항목을 회전

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

* ($ i -eq $ size) {, @ ($ array)}} else {, 함수 내에서 보상 할 수있는 방법이 없습니다. * 정말요? 그것은 당신을 위해 작동하지 않습니다 :'$ myWindows = @ (0 .. ($ a.Length- $ w) | % {, $ a [$ _ .. ($ _ + $ w-1)]})'? – PetSerAl

+0

@PetSerAl 예를 들어 (두 번째 마지막 코드 블록). 만약 당신이 기존 어레이를 무언가에 파이프하고 싶고 ('$ a | Select-Window'처럼) 윈도우를 처리 할 수 ​​있다면, 함수는 한번에 하나의 항목을받을 것이기 때문에 그렇게 할 수는 없습니다. 다른 배열 요소에 액세스 할 수 없습니다.호출자는 다음을 보상해야합니다.', $ a | 선택 창 '을 선택하십시오. – briantist

+1

'0 .. ($ a.Length- $ w) | % {, $ a [$ _ .. ($ _ + $ w-1)]} | % { "단일 배열 at time : $ _"}' – PetSerAl

관련 문제