You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Update for clarification: The gist of this proposal is to bring valuable filter functionality that currently only exists in the in-memory.Where() array method to its pipeline counterpart, Where-Object.
(Always using .Where() isn't an option with large input sets, because you'd have to collect all input in memory first.)
The .Where() array method, which is the in-memory equivalent of the pipeline-based Where-Object cmdlet, offers a number of additional features, such as the ability to optionally stop matching after the first match is found, which can be an important optimization technique, and the ability to output all objects that come before/after a matching one:
First / -First example:
# OK - very fast, because - despite the large input collection - processing stops after the first match.
(1..1e6).Where({ $_-eq10 },'First') # -> 10# WISHFUL THINKING: Add a -First switch (among several others - see below).1..1e6|Where-Object { $_-eq10 } -First
# Without it, ALL elements are processed - SLOW1..1e6|Where-Object { $_-eq10 }
# Current workaround is cumbersome.1..1e6|Where-Object { $_-eq10 } |Select-Object-First 1
Based on the current .Where() features, the following switches should be introduced with the same behavior, mirroring the WhereOperatorSelectionMode enumeration values:
-First, -Last, -SkipUntil, -Until, -Split
Note:
-Split partitions the input into two and returns two collections, so it would in effect require collecting all input in memory first before producing output, which would have to be clearly documented.
The .Where() method has an optional numeric parameter, numberToReturn, that modifies the operations, such as 2 with First returning the first two matches; since we don't have a syntax for switches with optional (non-Boolean) arguments for commands (see Feature Request: Variable Parameter with switch-like capability #12104), we have the following options:
Option A: Simply omit this aspect of the functionality and invariably default to 1, which is likely fine in the majority of cases; if a different number is needed, Select-Object -First/-Last $n can be piped to.
Option B: Implement -First and -Last not as _switches, but as -First and-Last ` ; the potential downside is that a number argument is then mandatory.
Option C: Given that numberToReturn also modifies all other functionality - though there's likely less of a need for that - implement a separate -Count <int> parameter, which in the absence of any of the switches would imply -First.
For these behaviors to be implemented efficiently, they have to stop the pipeline on demand, as Select-Object already does. However, the latter does so in a problematic fashion - not giving other cmdlets a chance to run their End blocks - which should be addressed (independently) as well: see Select-Object -First X skips End{ } blocks of previous cmdlets #7930
On a meta note: You can skip the obsolete comments that follow and resume reading at this comment.
Summary of the new feature/enhancement
Update for clarification: The gist of this proposal is to bring valuable filter functionality that currently only exists in the in-memory
.Where()array method to its pipeline counterpart,Where-Object.(Always using
.Where()isn't an option with large input sets, because you'd have to collect all input in memory first.)The
.Where()array method, which is the in-memory equivalent of the pipeline-basedWhere-Objectcmdlet, offers a number of additional features, such as the ability to optionally stop matching after the first match is found, which can be an important optimization technique, and the ability to output all objects that come before/after a matching one:First/-Firstexample:SkipUntil/-SkipUntilexample:Based on the current
.Where()features, the following switches should be introduced with the same behavior, mirroring theWhereOperatorSelectionModeenumeration values:-First,-Last,-SkipUntil,-Until,-SplitNote:
-Splitpartitions the input into two and returns two collections, so it would in effect require collecting all input in memory first before producing output, which would have to be clearly documented.The
.Where()method has an optional numeric parameter,numberToReturn, that modifies the operations, such as2withFirstreturning the first two matches; since we don't have a syntax for switches with optional (non-Boolean) arguments for commands (see Feature Request: Variable Parameter with switch-like capability #12104), we have the following options:Option A: Simply omit this aspect of the functionality and invariably default to
1, which is likely fine in the majority of cases; if a different number is needed,Select-Object -First/-Last $ncan be piped to.Option B: Implement
-Firstand-Last not as _switches, but as-Firstand-Last ` ; the potential downside is that a number argument is then mandatory.Option C: Given that
numberToReturnalso modifies all other functionality - though there's likely less of a need for that - implement a separate-Count <int>parameter, which in the absence of any of the switches would imply-First.For these behaviors to be implemented efficiently, they have to stop the pipeline on demand, as
Select-Objectalready does. However, the latter does so in a problematic fashion - not giving other cmdlets a chance to run theirEndblocks - which should be addressed (independently) as well: see Select-Object -First X skips End{ } blocks of previous cmdlets #7930On a meta note: You can skip the obsolete comments that follow and resume reading at this comment.