PotatoUser
PotatoUser

Reputation: 159

Switch handling with global arrays

Say I have 2 global arrays:

$Global:Values  = @(1..100)
$Global:Test = @(75, 50, 25, 101)

Then I create a Switch by piping $Global:Test into a ForEach loop by using different conditions which I tried troubleshooting to get any kind of response:

$Global:Test | ForEach-Object ($_) {
    $_
    Switch ($_) {
        ($_ -contains $Global:Values) {Write-Host "Excellent"}
        ($_ -in $Global:Values) {Write-Host "Satisfactory"}
        ($_ -eq "25") {Write-Host "Unsatisfactory"}
        Default {Write-Host "Invalid Grade"}
    }
}

Output:

75
Invalid Grade
50
Invalid Grade
25
Invalid Grade
101
Invalid Grade

All of these switch statements do not work except the default. I don't know what I'm missing, but I'm sure it's a simple mistake I'm overlooking. Can anyone help me spot this mistake?

Upvotes: 2

Views: 65

Answers (1)

briantist
briantist

Reputation: 47832

The foreach() statement is not the same as the ForEach-Object cmdlet, and you seem to be combining the syntax of both.

Additionally, you're using the switch statement incorrectly.

The part you're trying to match against needs to be a value:

switch ($something)
{
    5 { "5 thing" }
    (10 + 10) { "20 thing" }
}

or a scriptblock expression that returns a truthy or falsey value:

switch ($something)
{
    { $_ -gt 5 } { "do > 5 thing" }
    { Test-SomeCondition -Value $_ } { "do other thing" }
}

So you want the scriptblock form, but you're using parentheses.

So here's the ForEach-Object form:

$Global:Test | ForEach-Object {
    Switch ($_) {
        {$_ -contains $Global:Values} {Write-Host "Excellent"}
        {$_ -in $Global:Values} {Write-Host "Satisfactory"}
        "25" {Write-Host "Unsatisfactory"}
        Default {Write-Host "Invalid Grade"}
    }
}

or the foreach form:

foreach($value in $Global:Test) {
    Switch ($value) {
        {$_ -contains $Global:Values} {Write-Host "Excellent"}
        {$_ -in $Global:Values} {Write-Host "Satisfactory"}
        "25" {Write-Host "Unsatisfactory"}
        Default {Write-Host "Invalid Grade"}
    }
}

Also of note, the switch statement can actually work directly with arrays, so you don't have to iterate first. Basic example:

switch (1..10)
{
    { $_ -gt 5 } { "Second Half"}
    default: { "First Half" }
}

So with yours, maybe:

Switch ($Global:Test) {
    {$_ -contains $Global:Values} {Write-Host "Excellent"}
    {$_ -in $Global:Values} {Write-Host "Satisfactory"}
    "25" {Write-Host "Unsatisfactory"}
    Default {Write-Host "Invalid Grade"}
}

Small addendum: stop using Global variables!

Upvotes: 3

Related Questions