2016-04-29 38 views
2

我不很明白這一點,但爲什麼不將下面的代碼無法正常工作:的foreach一個管道數陣列心不是打破正常

"start" 
1..5 | foreach { 
    "$_" 
    break 
} 
"stop" 

我已經做了幾個測試和驗證碼不正常工作:

"start" 
foreach ($num in 1..5){ 
    "$num" 
    break 
} 
"stop" 

有沒有辦法讓第一個例子正常運行?最後輸出的行應該是「停止」。

像這樣:

start 
1 
stop 

回答

2

首先,你應該知道,你正在使用兩個完全不同的語言功能,當您使用foreach ($thing in $things) {}$things | foreach { }

第一個是內置的foreach聲明,第二個是ForEach-Object的別名,它們的工作方式非常不同。

ForEach-Object爲每個項目運行腳本塊,並且它在管道內工作。

該案例中的break陳述僅爲break從當前項目的執行中刪除。所謂的「父母」不知道由於break而退出的腳本塊會繼續執行下一個對象的腳本塊。


你如何去限制結果取決於你想要做什麼。

如果你只是想停止產生結果,只要條件得到滿足就不會返回任何東西。你仍然會運行每次迭代,但結果是正確的。

如果你只需要(從PowerShell的V3)返回一定數量的項目,像第一個N的項目,最好的辦法是增加Select-Object

1..10 | ForEach-Object { 
    $_*2 
} | Select-Object -First 5 

這將只執行5次,它將返回序列2,4,6,8,10

這是因爲管道是如何工作的,其中每個對象都通過每個cmdlet發送,並且Select-Object可以停止管道,因此它不會繼續執行。

在版本3.0之前,管道不能以這種方式停止,雖然結果是正確的,但您不會阻止額外的執行。

如果您提供更多關於您的退出條件的詳細信息,我可以提供更多關於如何處理特定問題(可能涉及不使用ForEach-Object)的信息。

+0

你提到PSv3。 select-object在v3之前的行爲有何不同? –

+0

@AnthonyStringer我已經編輯回答 – briantist