Michel Balencourt
Michel Balencourt

Reputation: 156

How to "if" on multiple entries of an array?

I'm wondering if there's a way to simplify the code below by having an if statement that checks if a value matches one of the entries of an array...

The code I ended up with:

foreach ($sourceLine in $source) {
    $sourceAVTrim = $sourceLine.ID.Remove(0, 1)
    $sourceAV = "av" + $sourceAVTrim

    if ($SourceLine.MAC -like "VCO*" -or $SourceLine.MAC -like "FOO*" -or $SourceLine.MAC -like "HOM*" -or $SourceLine.MAC -like "EOP*" -or $SourceLine.MAC -like "PCP*" -or $SourceLine.MAC -like "BUI*" -or $SourceLine.MAC -like "DML*") {
        if ($SourceLine.MAC -like "*ADM" -or $SourceLine.MAC -like "*SAL" -or $SourceLine.MAC -like "*PLA" -or $SourceLine.MAC -like "*PLN" -or $SourceLine.MAC -like "*PLC" -or $SourceLine.MAC -like "*PLS") {
            Write-Host "$($SourceAV) will NOT receive SMS - $($SourceLine.MAC)" -ForegroundColor Red
        } else {
            Write-Host "$($SourceAV) will receive SMS - $($SourceLine.MAC)" -ForegroundColor Green
        }
    } else {
        Write-Host "$($SourceAV) will NOT receive SMS - $($SourceLine.MAC)" -ForegroundColor Red
    }
}

But how can I set 2 arrays instead and have IF check my value against each entry?

$startMACs = @("VCO","FOO","HOM","EOP","PCP","BUI","DML")
$endMACs = @("ADM","SAL","PLA","PLN","PLC","PLS")

Upvotes: 1

Views: 89

Answers (2)

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200553

For exact matches you could use the -contains or -in operator. However, in your case you want a partial match against multiple strings, so I'd go with a regular expression.

$startMACs = 'VCO', 'FOO', 'HOM', 'EOP', 'PCP', 'BUI', 'DML'
$pattern = ($startMACs | ForEach-Object { [Regex]::Escape($_) }) -join '|'

if ($SourceLine.MAC -match "^($pattern)") {
    ...
} else {
    ...
}

^ anchors the expression at the beginning of a line, so you'll get the matches beginning with those substrings.

To anchor the expression at the end of a line (so you'll get the matches ending with the substrings) replace "^($pattern)" with "($pattern)$".

$pattern is constructed as an alternation (VCO|FOO|HOM|...), meaning "match any of these substrings" ("VCO" or "FOO" or "HOM" or ...).

Escaping the individual terms before building the pattern is so that characters with a special meaning in regular expressions (like for instance . or *) are treated as literal characters. It's not required in this case (since there are no special characters in the sample strings), but it's good practice so that nothing unexpected happens should someone update the list of strings with values that do contain special characters.

Upvotes: 5

boxdog
boxdog

Reputation: 8442

Since your patterns all start with a 3 letter code, one possibility is to grab the start of the target string and match using the -in operator with the pattern collection:

$startMACs = @("VCO","FOO","HOM","EOP","PCP","BUI","DML","HDOM")

if($SourceLine.MAC.Substring(0,3) -in $startMACs) {
    # Do something
}

So, if $SourceLine.MAC is, say, EOP123, the substring() call grabs the EOP part, then compares it to each entry in the $startMACs array, returning true if it finds a match, and false otherwise - should be true in this example.

You can do something similar for the end patterns:

$endMACs = @("ADM","SAL","PLA","PLN","PLC","PLS")

if($SourceLine.MAC.Substring($SourceLine.MAC.Length - 3,3) -in $endMACs) {
    # Do something
}

Upvotes: 3

Related Questions