Reputation: 34559
I'm trying to test if a condition is true for all items in an array in PowerShell (similarly to LINQ's All
function). What would be the 'proper' way to do this in PowerShell, short of writing a manual for-loop?
To be specific, here is the code I'm trying to translate from C#:
public static IEnumerable<string> FilterNamespaces(IEnumerable<string> namespaces)
=> namespaces
.Where(ns => namespaces
.Where(n => n != ns)
.All(n => !Regex.IsMatch(n, $@"{Regex.Escape(ns)}[\.\n]")))
.Distinct();
Upvotes: 2
Views: 2163
Reputation: 54911
I wouldn't recreate the C#-code in powershell, but rather do it the PowerShell-way. Ex:
function Filter-Namespaces ([string[]]$Namespaces) {
$Namespaces | Where-Object {
$thisNamespace = $_;
(
$Namespaces | ForEach-Object { $_ -match "^$([regex]::Escape($thisNamespace))\." }
) -notcontains $true
} | Select-Object -Unique
}
Filter-Namespaces -Namespaces $values
System.Windows.Input
System.Windows.Converters
System.Windows.Markup.Primitives
System.IO.Packaging
However, to answer your question, you could do it the manual way:
$values = "System",
"System.Windows",
"System.Windows.Input",
"System.Windows.Converters",
"System.Windows.Markup",
"System.Windows.Markup.Primitives",
"System.IO",
"System.IO.Packaging"
($values | ForEach-Object { $_ -match 'System' }) -notcontains $false
True
Or you could create a function for it:
function Test-All {
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
$Condition,
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
$InputObject
)
begin { $result = $true }
process {
$InputObject | Foreach-Object {
if (-not (& $Condition)) { $result = $false }
}
}
end { $result }
}
$values = "System",
"System.Windows",
"System.Windows.Input",
"System.Windows.Converters",
"System.Windows.Markup",
"System.Windows.Markup.Primitives",
"System.IO",
"System.IO.Packaging"
#Using pipeline
$values | Test-All { $_ -match 'System' }
#Using array arguemtn
Test-All -Condition { $_ -match 'System' } -InputObject $values
#Using single value argument
Test-All -Condition { $_ -match 'System' } -InputObject $values[0]
Or you could compile the C# code or load an already compiled dll using Add-Type
.
Upvotes: 7