2012-10-31 96 views
1

當您在過濾器中時是否有任何結束管道操作的方法?結束管道操作

一個很好的用法是獲取列表的前n個元素,類似於SQL的TOP語句。如果我們寫了一個過濾器,把它稱爲「頂級」,我們可以獲取前3個元素,像這樣:

dir | Top 3 

一旦我們回到前三,我們不需要處理任何更多的元素和效果我們希望能夠告訴管

請不要給我任何更多的元素

我知道,選擇-對象具有 - 第一的說法,但不是我的問題問。

我已經回答了問題Powershell equivalent to F# Seq.forall,而是我寧願將它實現爲結束流水線輸入的過濾器。如果有所謂的「最終流水線」操作,我將實現作爲的ForAll:

filter ForAll([scriptblock] $predicate) { 
    process { 
     if (@($_ | Where-Object $predicate).Length -eq 0) { 
      $false; 
      end-pipeline; 
     } 
    } 
    end { 
     $true; 
    } 
} 

回答

2

你可以使用 「突破」 的聲明,這將表現爲你的「最終管道「cmdlet

+1

它的工作原理。然而,基督徒提供的鏈接http://powershell.com/cs/blogs/tobias/archive/2010/01/01/cancelling-a-pipeline.aspx對於結束一條管道做了大量工作。是否可以安全地在所有情況下使用「休息」聲明? –

+0

一般來說,它是安全的,但是如果你調用一個包含break的腳本文件,而這個腳本文件不在某些循環中,比如while等等,它可能會中斷整個腳本的執行。 – Jackie

+0

@TahirHassan - break將停止其餘部分腳本執行。試試:'0..9 | 。{process {if($ _ -lt 5){$ _} else {break;}}} |測量;寫'結束'。請注意,在該例中,「measure」不會返回任何內容,「end」不會被打印。您可以將整個管道封裝在'try..catch'中,但管道末端的measure命令仍然不起作用。我一直在試圖找到一個很好的解決這個問題,但還沒有;請參閱我的問題http://stackoverflow.com/q/8749206/291709 – Rynant

1

也許你可以添加一個return如果達到條件。

here對於一些示例

這也許工作:

filter ForAll([scriptblock] $predicate) 
{ 
    process 
     {   
      if (@($input | Where-Object $predicate).length -eq 0) 
       {   
       $false 
       return; 
       } 
     } 
    end  
     { 
      $true 
     } 
} 

這個工程:

filter aaa {  
process 
{  
    if (++$i -gt 5) 
    { 
     return 
    } 
    else 
    { 
     $_ 
    } 
} 
} 

dir | aaa # return first five element of the pipe... 
+0

感謝您的鏈接 - 我會檢查出來。 –

+0

我試過返回 - 它返回的過程塊,而不是過濾器。 –

+0

這仍然執行每個元素的進程塊...我想停止處理。使用「break」正如傑基建議的那樣。 –

相關問題