Check out CGSE Powershell tips.
Left-operand casting
Powershell will always take the type of the left operand to determine what the type of the final expression will be
1+"2" # 3
"1"+2 # "12"
Implicit casting
You use a string in arithmetic operations, and you can interestingly use suffixes and prefixes too:
"0x$h" # convert hex string to number
"0b$b" # convert binary string to number
The n
suffix is useful to create large BigInts like powers of ten:
[bigint]::Pow(10,50)
(0n)::Pow(10,50)
'10n*'*50+1|iex
"1$('0'*50)n"
'9'*50+'n'
Accessing static methods via instances
You don't need to spell out the entire library name when using the method:
[Math]::pow(10,$x)
(0n)::pow(10,$x)
$x=4,2,3
[Array]::sort($x)
$x::Sort($x)
"$x" # 2 3 4
[Array]::Reverse($x)
$x::Reverse($x)
"$x" # 4 3 2
Wildcards
Wildcards are super useful in powershell golf. Here is a list of some of them:
String.EnumerateRunes *es
Rune.Value V*
String.ToCharArray t*y
String.Substring Su*
String.Replace *ace
String.Trim *m
String.ToLower *wer
String.length le*
String.ToUpper *per
MatchInfo.Matches m*
String.Indexof i*f
String.Split sp*, s*t
String.PadLeft *ft
String.PadRight *ht
Convert.ToString *g
Note that it doesn't matter whether uppercase or lowercase Wildcards are used (the entire language is case insensitive).
This feature is very useful when obtaining the characters of a string (if you're ok with getting the acsii values):
$a.tochararray()
[char[]]$a
$a|% t*y
The |% t*y
is short for | ForEach-Object -Method ToCharArray
If you happen to want to use the characters (as numbers, e.g. if the string was "1738") instead, make sure to not use ($_-48)
$a|% t*y|%{($_-48)...}
$a|% t*y|%{+"$_"}
You can remove the +
sometimes due to automatic casting.
Now, sometimes you will be using a regex matching, and say you wanted to get the acsii value of a character that was matched:
$_-replace"regex",{[int][char]"$_"}
$_-replace"regex",{+[char]"$_"}
$_-replace"regex",{+"$_"[0]}
In some cases, using sls
combined with a m
wildcard can be shorter than using -match
if($x-match'pattern'){$matches}
$x|sls 'pattern'|% m*
$x|sls pattern|% m* # if there's no | in pattern
Aliases
Aliases are incredibly useful in powershell golf, some of the main ones include:
? Where-Object
% ForEach-Object
gu Get-Unique
sort Sort-Object
iex Invoke-Expression
Use Get-Alias
to see them all.
iex
iex
is extremely useful in some cases:
(...|measure -s).Sum
...-join'+'|iex
[math]::pow($a,$b)
(0n)::pow($a,$b)
"$a*"*$b+1|iex
...-join'+'|iex
may actually have a bigger save:
'+...'*$x|iex
Char ranges
Character ranges are pretty useful in the case that you need them:
32..68|%{[char]$_}
' '..'D'|%{$_}
while loop
Instead of the usual while loop:
while(condition){}
for(;condition){}
You can even put code before the ;
to save another byte if you have any code before the while.
Joining
If you want to join by spaces you can save a lot of bytes:
(...)-join" "
"$(...)"
Joining by nothing:
(...)-join""
-join(...)
If you are joining by a number, you don't need quotes around it. This works for -split
and -replace
too.
(...)-join'0'
(...)-join0
Getting the value of a regex match
Use a interpolation string instead of the longer function:
(regex_match).value
"$(regex_match)"
List of strings
Use echo
instead of using a list of strings:
("abc","cde","efg","hij")
echo abc cde efg hij