The 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.
$target = "Spooler", "Spork Client", "WinRM", "Spork Agent Service", "BITS","WSearch" $list = "winrm", "foo", "spooler", "spor*", "bar"
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.
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
If you get foo and bar then it works!
$list | Where-Object {(-Not($target -like $_))}
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 ‘\*’}
My contribution 🙂
$list | ForEach-Object { if (-not($target -like $_)) { Write-Output $_ } }
$list | Where-Object { -not ($target -match $PSItem) }
I wish I was elegant enough to come up with these one line solutions but I went about it a little differently https://gist.github.com/ulikabbq/5c738cdbc05bb5a4d0d1640abec4d3ad
foreach ($i in $List) {
If ($Target -like $i) {
echo $null
} Else {
Write-Host -NoNewline “$i ”
}
}
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
$list | Where-Object { -not ($target -match $_) }
$list.where({($target -join “”) -notmatch $_})
$list.Where{ -not ($target -like $PSItem) }
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 $_)})
“`
$list | Where-Object { !($target -like $_) }
$list | ? {!($target -match $_.ToString())}
$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.
foreach($item in $list) {
(@($target) -like $item).Count -gt 0
}
@($list) | where {$_ -xor ($target -like $_)}
$list | % { if (“$_” -in $target) {Write-Host “$_.”} }
$list | Where-Object {($target -notcontains $_) -and (!($target -like $_))}
Solution 1:
$target = “Spooler”, “Spork Client”, “WinRM”, “Spork Agent Service”, “BITS”,”WSearch”
$list = “winrm”, “foo”, “spooler”, “spor*”, “bar”
$Result=@()
$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”
$Result=@()
foreach ($Element in $List)
{
if (!($target -like $Element))
{
$Result += $Element
}
}
Write-Output $Result
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
}
$list | ? {!($target -match $_)}
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
}
}
$list | % {if (!($target -match $_)) {$_}}
You can do it in two ways:
1) Compare-Object -ReferenceObject $list -DifferenceObject $target
or
2) $list | Where-Object { -not ($target -like $_) }
Late to the game..
https://github.com/Dalcron/IronScripter/blob/master/JUN_7_2019_Challenge.ps1