Если требуется обработка подсчета и :
Выполнение собственного подсчета в блоке сценария ForEach-Object
- лучший способ избежать обработки в два прохода.
Проблема в том, что у меня уже есть этот счетчик, и я хочу проверить правильность результата этого счетчика.
ForEach-Object
надежно вызывается для каждого входного объекта, включая значения $null
, поэтому нет необходимости перепроверять.
Если вы хотите очиститель разделение обработки и подсчета, вы можете передать несколько -Process
блоков сценария в ForEach-Object
(в этом примере { $_ + 1 }
- это ввод- обработка блок сценария, а { ++$count }
- это входные данные - , считая один):
PS> 1..5 | ForEach-Object -Begin { $count = 0 } `
-Process { $_ + 1 }, { ++$count } `
-End { "--- count: $count" }
2
3
4
5
6
--- count: 5
Обратите внимание, что из-за странности в привязке параметров ForEach-Object
, передается -Begin
и-End
блоки сценариев на самом деле требуются для того, чтобы передать несколько блоков -Process
(на объект ввода);pass $null
если вам на самом деле не нужны -Begin
и / или -End
- см. этот выпуск GitHub .
Также обратите внимание, что переменная $count
живет в вызывающейобласть действия и не ограничивается вызовом ForEach-Object
;то есть $count = 0
потенциально обновляет существующую переменную $count
и, если она ранее не существовала, продолжает работать после вызова ForEach-Object
.
Если необходим только счет:
Measure-Object
- это командлет для использования с большими потоковыми коллекциями ввода в конвейере [1] :
В следующем примере генерируется 100 000 целых чисел одно за другим и Measure-Object
подсчитывает их одно за другим, не собирая весь ввод в память.
PS> (& { $i=0; while ($i -lt 1e5) { (++$i) } } | Measure-Object).Count
100000
Caveat : Measure-Object
игнорирует $null
значения во входной коллекции - см. этот выпуск GitHub .
Обратите внимание, что при подсчете входных объектовПоведение по умолчанию Measure-Object
, оно также поддерживает множество других операций, таких как суммирование -Sum
и усреднение (-Average
), опционально комбинируемых в одном вызове.
[1] Measure-Object
, как командлет , способен обрабатывать ввод в потоке fashion, что означает, что он считает объекты, которые он получает один за другим по мере их получения, что означает, что даже очень большие потоковые входные наборы (те, которые также созданы один за другим, такие как перечисление строкбольшого CSV-файла с Import-Csv
) можно обрабатывать без риска нехватки памяти - нет необходимости загружать входную коллекцию в целом в память. Однако, если (а) входной набор уже имеет в памяти, или (b) он может уместиться в память и производительность важна, тогда используйте (...).Count
.