Doing shorter comparisons in PowerShell

6

1

One of the annoying bits about PowerShell, which helps amplify its disadvantage against other languages in , is that there are no symbolic comparison or logical operators.

A comparison that could be as short as this:

$x<10&&$x>5

Has to be:

$x-lt10-and$x-gt5

This bloats the code for even the simplest of comparisons by about 50% compared to many other regular scripting and programming languages, never mind any golfing languages. Even an Excel formula for a similar comparison comes up shorter by one character!

=AND(A1<10,A1>5)

Another one that really bugs me:

$x==$k&&$i>9&&$i%10!=0

Has to be:

$x-eq$k-and$i-gt9-and$i%10-ne0

Interestingly, this one's exactly as long as the comparable formula for Excel, but that's mainly due to Excel's lack of a symbolic modulus operator.

=AND(A1=B1,C1>9,MOD(C1,10)<>0)

Is there a way this can be shortened at all, or is this strictly a limitation of the language? Are there any particular scenarios to keep in mind where shortcuts can be used for joining multiple comparisons?

Iszi

Posted 2013-11-26T18:12:21.337

Reputation: 2 369

1"Use GNU/Linux's bash instead!" - flag as offensive. ;) (those symbols are file IO redirection and PowerShell designers didn't want to overload them anymore. It also makes all the comparators take the same format -comparator instead of having a mix like < > == -contains -in -match) – TessellatingHeckler – 2015-12-18T02:38:09.560

2Use GNU/Linux's [tag:bash] instead! : (( 5 < x && x < 10)) ;-) – F. Hauri – 2013-11-27T21:15:02.763

Answers

3

I found a semi-edge case where a multiple comparison can be shortened. This is useful when you need to test two or more variables for equality, and only return true if all tests are true.

Instead of this:

$a-eq$b-and$c-eq$d

You might be able to do this:

"$a$c"-eq"$b$d"

It's worked for me in a Pisano Period script, where I changed:

$a-eq1-and$b-eq0

To:

"$a$b"-eq10

Another example:

$a-eq'apple'-and$b-eq'orange'

Can be cut down to:

"$a$b"-eq'appleorange'

Iszi

Posted 2013-11-26T18:12:21.337

Reputation: 2 369

2

Note that [int]$x is 0(i.e. false) for all $x in the interval [-0.5, 0.5], and not 0(i.e. true) for all $x outside of the interval ([int] rounds the number).

So, to check $x -lt $m -or $x -lt $n - you can use the following:

[int]( $a * $x + $b )

where $a = 1 / ( $n - $m ) and $b = ( $m + $n ) / ( 2 * ( $m - $n ) )

For example, to check that $x is not between 3 and 5, you have $a = 1 / 2 and $b = -2 so:

[int]($x/2-2)

which is two characters shorter than

$x-lt3-or$x-gt5

To reverse the condition (i.e. to check that $x is between 3 and 5), you could:

![int]($x/2-2)             

which is still shorter than

$x-ge3-and$x-le5

It may not always be possible to get a short expression - it depends, of course, on what you get for $a and $b. However, if $m = -$n then $b=0, so the expression becomes rather trivial, e.g. to check that a number is between -3 and 3 you can simply:

![int]($x/6)

Another possibility to consider is "1"[$x] which evaluates to "1" (i.e. true) if $x is rounded to -1 or 0, and "nothing" (i.e. false) otherwise. So, the expression will be true for all $x in the interval (-1.5, 0.5]. Note that -1.5 is not included in the interval, as [int]-1.5 = -2.

With this method you can shorten an expression such as $x -gt $m -and $x -le $n into:

"1"[ $a * $x + $b ]

If you do the math as above, you get: $a=-2/($m-$n) and $b=($m+3*$n)/(2*$m-2*$n).

So, for example:

$x-gt3-and$x-le5

becomes:

"1"[$x-4.5]

Danko Durbić

Posted 2013-11-26T18:12:21.337

Reputation: 10 241

2

You can also use the integer-to-boolean conversion trick mentioned by Danko to check prime numbers for inequality against other prime numbers. This could also work for composite numbers, provided that none of the numbers involved are evenly divisible by any of the others.

Example:

$x-ne$y-and$x-ne$z

Can be shortened to:

$x%$y-and$x%$z

Because non-zero integers are handled as True in PowerShell, any prime numbers will return True for $x%$y if they are different and False if they are the same.

Iszi

Posted 2013-11-26T18:12:21.337

Reputation: 2 369