我只是想知道我是否遺漏了任何檔案,或者是否有其他/更好的方法來消除對檔案的需求。也許我是唯一一個試圖從一組資料中Select-Object選擇-First X唯一實體的人。
基于下面的測驗,它看起來像使用Select-Object與所述-Unique開關和一些型別的限制器(First,Last,Skip,Index,等等)固有地導致要應用之前洗掉重復的限制器。這在概念上對我來說沒有意義,但似乎也沒有記錄。
我為這個糟糕的例子道歉,但考慮一個包含 20 個專案的陣列,每個專案出現兩次:
PS > $array = @() ; 1..10 | % { $array = $_ ; $array = $_ }
PS > $array -Join ','
1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10 ##Displaying the array on a single comma separated line
假設有人給了您$array,但您最多只能處理 5 個物件的輸入。過濾掉你得到的東西,你可能會想使用Select-Object. 一開始你最終有 5 個物件,但有重復,所以快速思考你只需添加-Unique開關,然后你意識到輸出仍然不太正確。
PS > ($array | Select-Object -First 5) -Join ','
1,1,2,2,3 ##5 objects as expected, but with duplicates
PS > ($array | Select-Object -Unique -First 5) -Join ','
1,2,3 ##No duplicates, but less than the expected 5 objects...
為了獲得我期望的結果,我需要Select-Object在回傳最終物件集之前洗掉重復項。雖然知道這一點并沒有錯,但對我來說,Select-Object使用它執行的操作順序似乎很奇怪,而且沒有任何檔案圍繞-Unique在cmdlet.
PS > ($array | Select-Object -Unique | Select-Object -First 5) -Join ','
1,2,3,4,5 ##This is my expected outcome, 5 objects returned without any duplicates
uj5u.com熱心網友回復:
事實上,-First/ -Last/ -Skip/ -Index/ -SkipIndex/-SkipLast引數適用于原始輸入的第一,和-Unique被施加到最終的輸出。
簡單的解決方法是使用兩個 Select-Object呼叫:一個查找唯一物件,另一個從唯一物件中選擇所需的數字:
PS> 1, 1, 2, 3 | Select-Object -Unique | Select-Object -First 2
1
2
更快,基于 LINQ 的替代方案,使用[System.Linq.Enumerable]::Distinct(); 請注意需要將陣列轉換為特定型別([int[]]此處)。
PS> [Linq.Enumerable]::Distinct([int[]] (1, 1, 2, 3)) | Select-Object -First 2
1
2
筆記:
雖然額外的
Select-Object呼叫確實增加了處理開銷,但整個命令有可能只處理所需數量的輸入物件,即一旦找到所需數量的唯一物件就停止處理。然而,隨著PowerShell的7.2的,似乎
Select-Object -Unique是實作效率低下,并意外地收集所有輸入第一個產生輸出之前,即使沒有概念上的理由這樣做:它應該能夠產生流輸出,即-有條件-輸出輸入物件當它們被接收時,因為它只需要考慮到目前為止已經接收到哪些輸入物件。與此相反
Sort-Object,這也提供了一個-Unique開關,它必然要收集所有輸入第一個產生輸出之前,因為所有輸入物件必須考慮正確的排序。從 PowerShell 7.2 開始,
Sort-Object -Unique實際上比Select-Object -Unique.至于如何
Select-Object -Unique以更高效的流方式實作:到目前為止看到的物件可以存盤在一個System.Collections.Generic.HashSet`1實體中,以便有效測驗輸入物件是否被認為等于已經輸出的物件;有關 PowerShell 示例,請參閱此答案。
如果 和 when
Select-Object -Unique是 fixed,則權衡如下:感興趣的輸出物件相對于所有輸入物件的比例越小,您使用的效果就越好
Select-Object -Unique(即使您必須在之后對結果物件進行排序)。如果您無論如何都需要輸出/考慮所有輸入物件,并假設需要/可接受按排序順序輸出感興趣的物件,
Sort-Object則是更好的選擇。
首先測驗 cmdlet 是生成流輸出還是收集所有輸入:
除了檢查 cmdlet 的源代碼之外,還有一種測驗方法 -中間管道段是要測驗的命令:
# Test Sort-Object -Unique
# Because the command cannot stream, for conceptual reasons,
# it takes a while for the one and only output object to appear.
1..1e5 | Sort-Object -Unique | Select-Object -First 1
# Test Select-Object -Unique
# The command *could* stream, conceptually speaking, in which case
# the output object would appear right away.
# However, as of PowerShell 7.2, the command isn't implemented
# in a streaming fashion, so it takes a - surprisingly long - while
# for the output object to appear.
# it takes a while for the one and only output object to appear.
1..1e5 | Select-Object -Unique | Select-Object -First 1
If the given pipeline above produces its one and only output object near instantly, the command of interest is streaming; if it takes a while before the output object appears, it collects all input first.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/316401.html
下一篇:對匯入CSV的限制?
