I already know how to check if a string in an array DOES start with some character:
foreach ($str in $arr) {
if ($str.StartsWith("abc")) {
do this
}
}
But I need the code that will have somewhat different logic: "if no string in this array starts with abc, then do this"
Please help me to build code for that with the means of Powershell. I have no clue.
CodePudding user response:
Keeping the code you already have and showing a different alternative, you can loop through each element of the array and when the condition becomes true you can return $true
and break
your loop as no further comparison is needed:
$comparison = foreach ($str in $arr) {
if ($str.StartsWith("abc")) {
$true
break
}
}
if(-not $comparison) {
# here is if no element of `$arr` starts with abc
}
CodePudding user response:
The -like
comparison operator will act as a filter when you apply it to an array - making it easy to determine if any string in the array starts with abc
:
if(@($arr) -like 'abc*'){
# at least 1 string in $arr starts with abc
}
To get the opposite, use the -not
operator:
if(-not(@($arr) -like 'abc*')){
# no string in $arr starts with abc
}
CodePudding user response:
Using your example:
foreach ($str in $arr) {
if (-not $str.StartsWith("abc")) {
do this
}
}
Or,
$Filter = @('abc', 'def', 'abcghj') | Where-Object { -not $_.startswith('a') }
Then you can iterate over $Filter
CodePudding user response:
Using member-access enumeration and this comparison operator feature:
When the input of an operator is a scalar value, the operator returns a Boolean value. When the input is a collection, the operator returns the elements of the collection that match the right-hand value of the expression. If there are no matches in the collection, comparison operators return an empty array. For example:
if (!($Arr.StartsWith("abc") -eq $True)) {
'no string in $arr starts with abc'
}
If it concerns a very large array and you don't want to search further when any string starting with abc
is already found (as the helpful suggestion from Santiago), you might also use the PowerShell Where
method:
if (!($Arr.Where({ $_.StartsWith("abc") }, 'First'))) {
'no string in $arr starts with abc'
}
Note that in comparison with PowerShell's native case sensitivity the .Net StartsWith
method is case sensitive.
CodePudding user response:
This is not an answer, it is a performance test, and results, of the answers
This is the test code and results for the code examples provided by Mathias, iRon, and Santiago.
If anyone spots any errors, logic or otherwise, please let me know so I can correct it.
Setup for the test:
Defines the array and variables used in the test.
function Get-RandomAlphaNumericString{
[OutputType([string])]
param (
[parameter(Mandatory = $false, Position = 0)]
[ValidateScript({$_ -gt 0})]
[int]$Length = 1
)
[char[]]$Chars = [char[]]::new($Length)
for ($i = 0; $i -lt $Length; $i ) {
$Chars[$i] = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'[(Get-Random -Maximum 62)]
}
return [string]::new($Chars)
}
function Get-RandomAlphaNumericStrings{
[OutputType([string[]])]
param (
[parameter(Mandatory = $false, Position = 0)]
[ValidateScript({$_ -gt 0})]
[int]$ArrayLength = 1,
[parameter(Mandatory = $false, Position = 1)]
[ValidateScript({$_ -gt 0})]
[int]$StringLength = 1
)
[string[]]$Strings = [string[]]::new($ArrayLength)
for ($i = 0; $i -lt $ArrayLength; $i ) {
$Strings[$i] = Get-RandomAlphaNumericString $StringLength
}
return $Strings
}
$ArraySize = 100000
$LoopCount = 100
$arr = Get-RandomAlphaNumericStrings $ArraySize 20
[int]$IdxAt10Percent = $arr.Length * 0.1
[int]$IdxAt50Percent = $arr.Length * 0.5
[int]$IdxAt90Percent = $arr.Length * 0.9
$At10PercentPrefix = $arr[$IdxAt10Percent].Substring(0, 3)
$At50PercentPrefix = $arr[$IdxAt50Percent].Substring(0, 3)
$At90PercentPrefix = $arr[$IdxAt90Percent].Substring(0, 3)
$IsMissingPrefix = '###'
$At10PercentLike = $At10PercentPrefix '*'
$At50PercentLike = $At50PercentPrefix '*'
$At90PercentLike = $At90PercentPrefix '*'
$ThatIsMissingLike = $IsMissingPrefix '*'
Mathias test code:
Write-Host "`nMathias:"
Write-Host " Array of $ArraySize elements"
Write-Host " Repeat for $LoopCount loops"
$NotFound = $false
Measure-Command {
for ($i = 0; $i -lt $LoopCount; $i ) {
if(-not(@($arr) -like $At10PercentLike)){
$NotFound = $true
}
}
} | ForEach-Object { Write-Host "Index Position = ${IdxAt10Percent}: { $($_.Seconds $_.Milliseconds/1000) seconds }"}
$NotFound = $false
Measure-Command {
for ($i = 0; $i -lt $LoopCount; $i ) {
if(-not(@($arr) -like $At50PercentLike)){
$NotFound = $true
}
}
} | ForEach-Object { Write-Host "Index Position = ${IdxAt50Percent}: { $($_.Seconds $_.Milliseconds/1000) seconds }"}
$NotFound = $false
Measure-Command {
for ($i = 0; $i -lt $LoopCount; $i ) {
if(-not(@($arr) -like $At90PercentLike)){
$NotFound = $true
}
}
} | ForEach-Object { Write-Host "Index Position = ${IdxAt90Percent}: { $($_.Seconds $_.Milliseconds/1000) seconds }"}
$NotFound = $false
Measure-Command {
for ($i = 0; $i -lt $LoopCount; $i ) {
if(-not(@($arr) -like $ThatIsMissingLike)){
$NotFound = $true
}
}
} | ForEach-Object { Write-Host "Missing: { $($_.Seconds $_.Milliseconds/1000) seconds }"}
iRon's test code:
Write-Host "`niRon:"
Write-Host " Array of $ArraySize elements"
Write-Host " Repeat for $LoopCount loops"
$NotFound = $false
Measure-Command {
for ($i = 0; $i -lt $LoopCount; $i ) {
if (!($Arr.StartsWith($At10PercentPrefix) -eq $True)) {
$NotFound = $true
}
}
} | ForEach-Object { Write-Host "Index Position = ${IdxAt10Percent}: { $($_.Seconds $_.Milliseconds/1000) seconds }"}
$NotFound = $false
Measure-Command {
for ($i = 0; $i -lt $LoopCount; $i ) {
if (!($Arr.StartsWith($At50PercentPrefix) -eq $True)) {
$NotFound = $true
}
}
} | ForEach-Object { Write-Host "Index Position = ${IdxAt50Percent}: { $($_.Seconds $_.Milliseconds/1000) seconds }"}
$NotFound = $false
Measure-Command {
for ($i = 0; $i -lt $LoopCount; $i ) {
if (!($Arr.StartsWith($At90PercentPrefix) -eq $True)) {
$NotFound = $true
}
}
} | ForEach-Object { Write-Host "Index Position = ${IdxAt90Percent}: { $($_.Seconds $_.Milliseconds/1000) seconds }"}
$NotFound = $false
Measure-Command {
for ($i = 0; $i -lt $LoopCount; $i ) {
if (!($Arr.StartsWith($IsMissingPrefix) -eq $True)) {
$NotFound = $true
}
}
} | ForEach-Object { Write-Host "Missing: { $($_.Seconds $_.Milliseconds/1000) seconds }"}
Santiago's test code:
Write-Host "`nSantiago:"
Write-Host " Array of $ArraySize elements"
Write-Host " Repeat for $LoopCount loops"
$NotFound = $false
Measure-Command {
for ($i = 0; $i -lt $LoopCount; $i ) {
$comparison = foreach ($str in $arr) {
if ($str.StartsWith($At10PercentPrefix)) {
$true
break
}
}
if(-not $comparison) {
$NotFound = $true
}
}
} | ForEach-Object { Write-Host "Index Position = ${IdxAt10Percent}: { $($_.Seconds $_.Milliseconds/1000) seconds }"}
$NotFound = $false
Measure-Command {
for ($i = 0; $i -lt $LoopCount; $i ) {
$comparison = foreach ($str in $arr) {
if ($str.StartsWith($At50PercentPrefix)) {
$true
break
}
}
if(-not $comparison) {
$NotFound = $true
}
}
} | ForEach-Object { Write-Host "Index Position = ${IdxAt50Percent}: { $($_.Seconds $_.Milliseconds/1000) seconds }"}
$NotFound = $false
Measure-Command {
for ($i = 0; $i -lt $LoopCount; $i ) {
$comparison = foreach ($str in $arr) {
if ($str.StartsWith($At90PercentPrefix)) {
$true
break
}
}
if(-not $comparison) {
$NotFound = $true
}
}
} | ForEach-Object { Write-Host "Index Position = ${IdxAt90Percent}: { $($_.Seconds $_.Milliseconds/1000) seconds }"}
$NotFound = $false
Measure-Command {
for ($i = 0; $i -lt $LoopCount; $i ) {
$comparison = foreach ($str in $arr) {
if ($str.StartsWith($IsMissingPrefix)) {
$true
break
}
}
if(-not $comparison) {
$NotFound = $true
}
}
} | ForEach-Object { Write-Host "Missing: { $($_.Seconds $_.Milliseconds/1000) seconds }"}
Typical PowerShell 5.1 results:
Mathias:
Array of 100000 elements
Repeat for 100 loops
Index Position = 10000: { 3.942 seconds }
Index Position = 50000: { 3.885 seconds }
Index Position = 90000: { 3.879 seconds }
Missing: { 3.878 seconds }
iRon:
Array of 100000 elements
Repeat for 100 loops
Index Position = 10000: { 17.431 seconds }
Index Position = 50000: { 17.449 seconds }
Index Position = 90000: { 17.47 seconds }
Missing: { 17.473 seconds }
Santiago:
Array of 100000 elements
Repeat for 100 loops
Index Position = 10000: { 1.118 seconds }
Index Position = 50000: { 5.461 seconds }
Index Position = 90000: { 9.859 seconds }
Missing: { 10.997 seconds }
Typical PowerShell Core 7.2.6 results:
Mathias:
Array of 100000 elements
Repeat for 100 loops
Index Position = 10000: { 1.082 seconds }
Index Position = 50000: { 1.08 seconds }
Index Position = 90000: { 1.077 seconds }
Missing: { 1.068 seconds }
iRon:
Array of 100000 elements
Repeat for 100 loops
Index Position = 10000: { 10.301 seconds }
Index Position = 50000: { 10.655 seconds }
Index Position = 90000: { 10.576 seconds }
Missing: { 10.633 seconds }
Santiago:
Array of 100000 elements
Repeat for 100 loops
Index Position = 10000: { 0.623 seconds }
Index Position = 50000: { 3.02 seconds }
Index Position = 90000: { 5.412 seconds }
Missing: { 5.984 seconds }