I have a PowerShell custom object with tags, i.e. {Tags = 11,12,13,14,15}
. I am trying to filter out objects that contain one or more of the tags. Thus far, I have tried this expression with no luck.
Title : Example One
Year : 2022
Id : 12345
Tags : {11, 15}
Title : Example Two
Year : 2022
Id : 12346
Tags : {14, 15}
Title : Example Three
Year : 2022
Id : 12347
Tags : {12, 13}
Code:
$Filter = ('11','14','15')
$Filtered_Objects = $Objects | Where-Object { $_.Tags -notin $Filter }
When I execute the above code, it returns all objects. What I am trying to filter out are objects Example One and Two, with only object Example Three remaining.
CodePudding user response:
Containment Operators can only compare a scalar (a single value) against a collection, however what you're attempting to do is compare 2 collections which the operators simply can't handle. You can however, enumerate the filtering collection ($Filter
) inside the Where-Object
scriptblock and check if any of the elements in filter is -in
the .Tags
collections, then return $false
else $true
. This would result in the object with ID = 12347
from your example.
$objects | Where-Object {
foreach($i in $Filter) {
if($i -in $_.Tags) { return $false }
}
$true
}
Another way to do it, using Enumerable.Any
Method from Linq:
$delegate = [Func[int, bool]]{ $args[0] -in $filter }
$objects | Where-Object {
-not [Linq.Enumerable]::Any([int[]] $_.Tags, $delegate)
}