Im importing a csv and have multiple filters that the end user can select to filter the csv.
foreach filter Im = to an array.
Problem I run into is-
If a user selects 'Medium' and USD, they should only be able to see Rows of data which has both 'Medium' from the impact column and USD from country.
My results are returning 'Medium' from any country AND 'USD' events?
I feel like Im going about this the wrong way. Any ideas? Thank you for your time.
$buttonFilter_Click={
$r = @()
#Filter Impact Column#
if ($checkboxLow.Checked -eq $true)
{
$r = $script:WorldWideNews | ? { $_.Impact -eq 'Low' }
}
if ($checkboxMedium.Checked -eq $true)
{
$r = $script:WorldWideNews | ? { $_.Impact -eq 'Medium' }
}
if ($checkboxHigh.Checked -eq $true)
{
$r = $script:WorldWideNews | ? { $_.Impact -eq 'High' }
}
#Filter Country column#
if ($checkboxUSD.Checked -eq $true)
{
$r = $script:WorldWideNews | ? { $_.Country -eq 'USD' }
}
if ($checkboxCHF.Checked -eq $true)
{
$r = $script:WorldWideNews | ? { $_.Country -eq 'CHF' }
}
if ($checkboxGBP.Checked -eq $true)
{
$r = $script:WorldWideNews | ? { $_.Country -eq 'GBP' }
}
if ($checkboxAUD.Checked -eq $true)
{
$r = $script:WorldWideNews | ? { $_.Country -eq 'AUD' }
}
if ($checkboxCNY.Checked -eq $true)
{
$r = $script:WorldWideNews | ? { $_.Country -eq 'CNY' }
}
if ($checkboxJPY.Checked -eq $true)
{
$r = $script:WorldWideNews | ? { $_.Country -eq 'JPY' }
}
if ($checkboxCAD.Checked -eq $true)
{
$r = $script:WorldWideNews | ? { $_.Country -eq 'CAD' }
}
if ($checkboxEUR.Checked -eq $true)
{
$r = $script:WorldWideNews | ? { $_.Country -eq 'EUR' }
}
if ($checkboxNZD.Checked -eq $true)
{
$r = $script:WorldWideNews | ? { $_.Country -eq 'NZD' }
}
$table = ConvertTo-DataTable -InputObject $r
Update-DataGridView -DataGridView $datagridviewUpcomingNews -Item $table
}
CodePudding user response:
Your code forms the union of all filter results, along both dimensions, impact and country (currency).
Instead, you need the intersection of the results from these two dimensions.
The immediate fix is to collect an intermediate result for the filtering performed along the first dimension, and then base the filtering along the second dimension on that:
$r = @()
#Filter Impact Column#
if ($checkboxLow.Checked)
{
$r = $script:WorldWideNews | ? { $_.Impact -eq 'Low' }
}
# ...
# Save the results of the impact filtering
# and base all subsequent filtering on that.
$impactFilterResults = $r
$r = @()
#Filter Country column# - note the use of $impactFilterResults as input.
if ($checkboxUSD.Checked)
{
$r = $impactFilterResults | ? { $_.Country -eq 'USD' }
}
if ($checkboxCHF.Checked)
{
$r = $impactFilterResults | ? { $_.Country -eq 'CHF' }
}
# ...
Note, however, that your code can be streamlined, by ultimately combining all filters into a composite one that a single Where-Object
(?
) call could perform:
$buttonFilter_Click = {
# Map the checkboxes to the corresponding values to filter by.
$impactValueMap = @{
$checkboxLow = 'Low'
$checkboxMedium = 'Medium'
$checkboxHigh = 'High'
}
# Based on which are checked, determine the list of values to filter by.
[array] $impactsToFilterBy = foreach ($checkbox in $checkboxLow, $checkboxMedium, $checkboxHigh) {
if ($checkbox.Checked) { $impactValueMap[$checkbox] }
}
# Note: Truncated to 3 entries for brevity
$countryValueMap = @{
$checkboxUSD = 'USD'
$checkboxCHF = 'CHF'
$checkboxGBP = 'GBP'
# ...
}
[array] $countriesToFilterBy = foreach ($checkbox in $checkboxUSD, $checkboxCHF, $checkboxGBP) {
if ($checkbox.Checked) { $countryValueMap[$checkbox] }
}
# Use a single Where-Object call to filter, based
# on *arrays* of values to match.
$r =
$script:WorldWideNews |
Where-Object { $_.Impact -in $impactsToFilterBy -and $_.Country -in $countriesToFilterBy }
$table = ConvertTo-DataTable -InputObject $r
Update-DataGridView -DataGridView $datagridviewUpcomingNews -Item $table
}