Coming from a C# background and being a complete PowerShell novice, I am trying to make a simple filtering based on two lists/arrays.
Goal: filter elements of list 'toFilter' based on list 'filter', so to only keep elements of 'toFilter', which are matching at least one of the patterns listed in 'filter'.
Ideally I would like to achieve that using piping or Linq (and not nested loops).
In C#, I would do it like this:
string[] filter = {"A", "B", "C"};
string[] toFilter = {"AA", "AB", "DD"};
var filtered = toFilter.Where(s1 => filter.Any(s2 => s1.Contains(s2))).ToList();
or even shorther, using method groups:
var filtered = toFilter.Where(s1 => filter.Any(s1.Contains)).ToList();
With the expected outcome of:
AA AB
For Powershell, I found an article which describes powershell equivalents of Linq in C#, but apparently I cannot grasp the syntax.
I came with a following solution:
$filter = @("A", "B", "C")
$toFilter = @("AA", "AB", "DD")
$filtered = $toFilter | where {[Linq.Enumerable]::Any([string[]]$filter, [Func[string,bool]]{ $_ -match $args[0] })}
But it results in an empty list.
What would be a correct way of using those two arrays to come with an expected result?
EDIT: Apparently my solution works, but it is not pure LINQ, so a question is still valid.
The reason your example fails is that $_ and $args[0] refer to the same thing in the inner delegate.
There's no need to employ LINQ here though - you can do the same with a nested Where-Object clause:
$filter = @("A", "B", "C")
$toFilter = @("AA", "AB", "DD")
$filtered = $toFilter | Where-Object {
$item = $_
@($filter |Where-Object {$item.Contains($_)}).Count -gt 0
}
Cards on the table this is my first day working with LINQ. It seems like something I would like to be able to use. I tried to nest LINQ statements as best I could to try and get the right results using only LINQ.
[Linq.Enumerable]::where(
$toFilter,
[System.Func[System.Object,bool]]{
param($filterItem)
[Linq.Enumerable]::Any(
$filter,
[Func[System.Object,bool]]{
param($singlefilter)
# write-host "$filterItem -match $singlefilter"
$filterItem -match $singlefilter}
)
}
)
Where to work over $toFilter and the Any checks each $filter against each $toFilter item.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With