GeezerVison is showing github.com — Allow Measure-Object to accept ad-hoc script-block arguments in lieu of property names · Issue #6855 · PowerShell/PowerShell
Allow Measure-Object to accept ad-hoc script-block arguments in lieu of property names #6855DescriptionThis issue arose out of #6837.
Motivation:
Sort-Object's -Property not only supports property names (the typical case), but also script blocks that are evaluated for each input object and thereby enable sorting criteria derived from properties, which is a powerful feature (also found, in essence, in Select-Object); e.g.:
# Sort by only the numerical part of the input, via a script-block parameter argument.
PS> 'z1', 'a0', 'b10' | Sort-Object -Property { [int] $_.Substring(1) }
a0
z1
b10
Suggestion:
It would be handy if Measure-Object supported analogous use; e.g.:
# Count the odd numbers in the input.
PS> 1, 2, 3 | Measure-Object -Sum -Property { $_ % 2 } # wishful thinking
2
To that end:
- The
-Property parameter's data type would have to change from[string[]] to [object[]]
- In the event of a script block getting passed, it would have to be evaluated for each input object and used in lieu of a simple property access on the input object.
Environment data
Written as of:
Activitychanged the title [-]Allow Measure-Object to accept ad-hoc script-block arguments [/-] [+]Allow Measure-Object to accept ad-hoc script-block arguments in lieu of property names[/+] on May 11, 2018BrucePay commented on May 15, 2018 It's actually just a 3-line change with Property going from [string[]] to [MshExpression[]]. The downside is that MshExpression is an internal (and unfortunately named) class. So about 30 files need to be changed to do this properly (rename MshExpression -> PSPropertyExpression and make it public.) mklement0 commented on May 15, 2018 ContributorAuthor More actions Thanks, Bruce Payette (@BrucePay), but wouldn't changing the type to [object[]] do, accompanied by internal logic to see if each object passed is either a [scriptblock] or a [string] (or something that can be coerced to a string)?
That's how Sort-Object seems to do it. BrucePay commented on May 15, 2018 MshExpression is a class that can be constructed from either a string or a scriptblock. It encapsulates the logic for extracting a property value from an object. It's already used by Measure-Object internally but because Property is typed as string, the script block aspect isn't exposed. Changing the parameter to be of type MshExpression automatically exposes the scriptblock functionality.
mklement0 commented on May 15, 2018 ContributorAuthor More actions Thanks, Bruce Payette (@BrucePay).
My point was that if Sort-Object types its -Property parameter [object[]] publicly and uses [MshExpression] internally, can't Measure-Object do the same, thereby saving us from having to make [a renamed] [MshExpression] public? SteveL-MSFT commented on May 16, 2018 @PowerShell/powershell-committee reviewed this. MshExpression should be called PSPropertyExpression and Measure-Object -Property type should be changed to PSPropertyExpression. Sort-Object can be fixed in a separate PR. This is a breaking change because the type is changing, but existing scripts should not be impacted as a string can be coerced to a PSPropertyExpression. mklement0 commented on May 18, 2018 ContributorAuthor More actions That's good to hear, Steve Lee (@SteveL-MSFT).
We should consider doing the same thing not only for Sort-Object, but also for Select-Object.
Note, however, that additional considerations apply, because both commands accept a hashtable in addition to a script block:
Sort-Object only requires a hashtable if you want to reverse the sort direction on a per property/expression basis:
PS> 'z1', 'a0', 'b10' | Sort-Object -Property @{ Descending=$True; Expression = { [int] $_.Substring(1) }
b10
z1
a0
- In the case of
Select-Object use of a hashtable is actually the typical case, because in the absence of a name for the property created by the script block the script block's literal string contents becomes the name:
# With just a script block, the resulting property name is the *expression source code*:
PS> 1 | Select-Object { $_ * 10 }
$_ * 10
---------
10
# Typical case: provide a hashtable wrapper for the expression that names the property:
PS> 1 | Select-Object @{ Name='TimesTen'; Expression = { $_ * 10 } }
TimesTen
--------
10
mklement0 commented on May 27, 2018 ContributorAuthor More actions P.S: In addition to later changing Sort-Object, Group-Object should be changed too. mklement0 commented on Jun 4, 2018 ContributorAuthor More actions ... and ConvertTo-Html - see #6994
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|