我在一個我認為運行良好的腳本中有這個,但似乎已經停止作業:
$testList = @("object 1","object 2","object 3","object 4","object 5")
$counter = 0
$maxSize = 2
$groupedList = $testList | Group-Object { [math]::Floor($counter / $maxSize) }
$groupedList
$groupedList | Measure-Object
以前 Measure-Object 會給我 3 個計數,但現在我收到 1 個計數。
為什么這不再起作用?計數器整數是否不再在 Group-Object 命令中增加?
uj5u.com熱心網友回復:
我認為您的命令從未按預期作業(有關詳細資訊,請參閱底部)。
代替:
{ [math]::Floor($counter / $maxSize) }
和:
{ [math]::Floor((Get-Variable -Scope 1 counter).Value / $maxSize) }
為了確保在腳本塊的呼叫中更新的是呼叫者的$counter變數。
筆記:
$script:counter也可以,但前提是呼叫范圍是腳本的頂級范圍。Get-Variable-Scope 1 counter明確地針對父作用域的定義$counter,即呼叫者的;為簡潔起見,您可以省略-Scope 1,因為默認情況下會回傳最近的祖先范圍內的變數。Santiago Squarzon提出了另一種選擇:
您可以將
$counter變數定義為具有.Value屬性的參考型別物件,而不是整數,最簡單的形式是哈希表:$counter = @{ Value = 0 }由于
$counter現在包含物件參考,腳本塊中的子范圍在查詢父范圍變數的值時會看到完全相同的物件$counter,并且可以更新其.Value屬性:{ [math]::Floor($counter.Value / $maxSize) }
問題是傳遞給(位置)隱含-Property引數的腳本塊Group-Object在子范圍內運行,因此在每次呼叫時都會$counter 隱式創建一個塊區域變數:
即
$counter不作用于父作用域中的現有變數;它隱式地創建變數的范圍本地副本($counter使用呼叫者的當前值),并應用于它。這個可能令人驚訝的行為 -當(表面上)分配給存在于祖先范圍內的變數時隱式創建區域變數 - 在這個答案中詳細討論。
在相關說明中,令人驚訝的是,這樣的腳本塊(通常包括計算屬性)在子范圍內運行,而不是直接在呼叫者的范圍內運行 - 請參閱GitHub 問題 #7157
由于您
是一個后增量,它是0作為除法運算的 LHS 運算元的原始值(從父范圍變數復制)/。退出腳本塊時,區域
$counter變數超出范圍,下一次呼叫從頭開始。
因此,實際上,腳本塊的回傳值是一個固定的0,所以你只會得到一個組。
Group-Object使用“分塊”的替代方法:
您用于Group-Object實作“分塊”(批處理、磁區,即將輸入拆分為固定大小的陣列)很優雅,但最終效率低下,而且它不是流式解決方案,因為必須預先收集所有輸入(這兩個方面都沒有)在特定情況下可能很重要)。
如果
Select-Object直接支持這樣的功能,那就太好了,這是GitHub 問題 #8270提出的,以-ReadCount引數的形式:# WISHFUL THINKING PS> 1..5 | Select-Object -ReadCount 2 | ForEach-Object { "$_" } 1 2 3 4 5這個答案提供了一個自定義函式
Select-Chunk,它實作了這個功能:# Assumes function Select-Chunk from the linked answer is defined. PS> 1..5 | Select-Chunk -ReadCount 2 | ForEach-Object { "$_" } 1 2 3 4 5
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/466230.html
