Shortening Property Names
Sadly, unlike parameters, properties/methods (anything accessed with a dot .
) cannot usually be shortened down to its unambiguous form.
But certain cmdlets can operate on property names and take wildcards, and there are little-known parameter sets of %
and ?
that can be useful.
Usually we pass in a scriptblock and refer to the item with $_
, but there's another form of these that takes a property name, and it accepts a wildcard.
$o|select Le*
$o|%{$_.Length}
With a property like .Length
we can't use the v3 magic that would normally work on an array because Length
is a property of the array itself, so the above two could be used to get the lengths of the individual members. The select
comes in a little bit shorter.
But %
can take a property name directly and return that value:
$a|% Length
Which can be shortened with wildcards. The wildcard must resolve to a single property (or method, more on that later), so it will throw a helpful error if it doesn't, indicating exactly which members it could resolve to.
In the case of Length
, Le*
is typically the shortest. Even on a single string, this method is 1 byte shorter than just using the property.
$a.Length # 9 #(doesn't work on array)
$a|%{$_.Length} # 15
$a|% Le* # 8
But depending on what you're doing with this, this can be worse. You can do $a.Length*5
but to do it with the pipeline expression you'd have to wrap it ($a|% Le*)*5
; might still be worth it if it's against an array, but the point is it's not always appropriate as a straight substitution.
It works with methods too, and you can leave off the ()
which makes a full name the same length, but same restriction as above about sometimes having to wrap it. The method must have an overload that takes no parameters (you can pass arguments by placing them after the method name, which is really nice):
$a.ToUpper() # 12
$a|% *per # 9
With arguments:
'gaga'-replace'g','r' # 21
'gaga'|% *ce g r # 16
These aren't strictly the same in that the -replace
operator does a regex replace, but if you're just doing a string replace, it can (now) be shorter to use the method; it helps that the strings are cmdlet arguments instead of method arguments so they don't need to be quoted.
Where-Object Properties
?
can take (partial) property names as well, and apply an "operator" to it (in the form of switch parameters). Again this can be shorter than using the standard Where-Object
scriptblock approach if the property name is sufficiently long and unique.
$a|?{$_.Length-gt5} # 19
$a|? Le* -GT 5 # 14
($a|% Le*)-gt5 # 14 - Lengths, not objs