Challenge

Let the PowerShell Challenges Begin

string playThe Chairman has decided that it is in the best interests of his Iron Scripters, and those that wish to attain that valued designation,  that training continue year-round. To that end, he has commissioned a series of PowerShell challenges. These challenges will range in complexity and be tagged accordingly. Although,  you are encouraged to try your hand at all posted challenges. Some solutions may require complex coding, perhaps a PowerShell function. Others might be no more than a line or two of PowerShell that you would type interactively in the console. You are encouraged to share your work in social media, blogs, or sites like GitHub.  You are welcome to post links to your work in comments to each challenge. Shall we begin?

For your first challenge exercise, consider these two arrays of strings.

Your goal is to find the values in $List that do not match anything in $Target. Your code will be successful if you get foo and bar for results. This exercise is classified with an Intermediate level.

Good Luck and check back later for a suggested solution.

30 thoughts on “Let the PowerShell Challenges Begin”

  1. It is the first time I am participating in such a challenge, hope I got it right, here’s my attempt at the code:

    $res = @()
    foreach ($item in $list) {
    if (-not ($target -match $item)) {
    $res +=$item
    }
    }
    Write-Output $res

  2. I struggled finding a way to exclude ‘spor*’ from the output. I feel like I cheated by adding the second where() that specifically excludes words with a ‘*’.

    Two formats below:

    $list.Where({$_ -notin $target}).Where({$_ -notmatch ‘\*’})
    $list | Where-Object {$_ -notin $target} | Where-Object {$_ -notmatch ‘\*’}

  3. My contribution 🙂
    $list | ForEach-Object { if (-not($target -like $_)) { Write-Output $_ } }

  4. foreach ($i in $List) {
    If ($Target -like $i) {
    echo $null
    } Else {
    Write-Host -NoNewline “$i ”
    }
    }

  5. Hi this my output
    $result = @()
    foreach ($i in $list) {

    $a = @()
    $a += foreach ($j in $target) {
    $j -like $i
    }
    if ($a -notcontains $true) {
    $result += $i
    }

    }
    After seeing others comments damn there are lot of easier ways to do

  6. I originally went down the path of $List.Where({$_ -notin $Target}) but, as mentioned by John above, this does not filter out the “spor*” list item which has two matches in $Target.

    One solution, builds an object array that contains the $List item and their corresponding $Target matches. The $MatchedListItems will clearly show what list item has no matches.


    $MatchedListItems = $List | ForEach-Object {
    [PSCustomObject]@{
    ListItem = $_
    TargetMatches = $Target -match $_
    }
    }
    $MatchedListItems.Where({-Not $_.TargetMatches}).ListItem

    $MatchedListItems

    ListItem TargetMatches
    -------- -------------
    winrm {WinRM}
    foo {}
    spooler {Spooler}
    spor* {Spooler, Spork Client, Spork Agent Service}
    bar {}

    At first, I was baffled as to why Spooler was matched by “spor*”, but a check on https://regex101.com/r/vQhwTv/1 shows that the ‘*’ is greedy. At least, that’s the best I can determine. Perhaps, Jeff could provide insight into this?

    This $MatchedListItems solution can then be simplified into the following succinct solution:


    $List.Where({-Not ($Target -match $_)})

  7. $list | ? {!($target -match $_)} (shortest i can think of)
    I was thinking $list | where {$_ -notin $target} at first but that does not qualify match..
    Ramesh his answer is best, i just made it a bit shorter.

  8. Solution 1:

    $target = “Spooler”, “Spork Client”, “WinRM”, “Spork Agent Service”, “BITS”,”WSearch”
    $list = “winrm”, “foo”, “spooler”, “spor*”, “bar”

    [email protected]()

    $list | ForEach-Object {if (!($target -like $_)){$Result += $_}}

    Write-Output $Result

    Solution 2:

    $target = “Spooler”, “Spork Client”, “WinRM”, “Spork Agent Service”, “BITS”,”WSearch”
    $list = “winrm”, “foo”, “spooler”, “spor*”, “bar”

    [email protected]()

    foreach ($Element in $List)
    {
    if (!($target -like $Element))
    {
    $Result += $Element
    }
    }

    Write-Output $Result

  9. function Compare-Lists($target, $item) {

    [System.Collections.ArrayList]$NoMatchArray = $list

    foreach ($listItem in $list) {
    foreach ($targetItem in $target) {
    if ($targetItem -like $listItem) {
    $NoMatchArray.Remove($listItem)
    break
    }
    }
    }

    return $NoMatchArray
    }

  10. foreach($listitem in $list)
    {
    $flag=0;
    for($i=0;$i -le $target.Count ;$i++)

    {
    if($target[$i] -like $listitem)
    {
    $flag=1
    }
    }

    if($flag -eq 0)
    {
    $listitem
    }
    }

  11. You can do it in two ways:

    1) Compare-Object -ReferenceObject $list -DifferenceObject $target

    or

    2) $list | Where-Object { -not ($target -like $_) }

Comments are closed.