C#使用Where(Linq)过滤具有四个条件的列表

本文关键字:四个 列表 条件 Where 使用 Linq 过滤 | 更新日期: 2023-09-27 18:27:28

我有一个从数据库(使用数据集)获得的列表:

IEnumerable<DataSet.spGetDataRow> MyList = new DataSetTableAdapters.spGetDataTableAdapter().GetData(Date1, Date2, PID, RID).ToList();    

我有4个复选框

<asp:CheckBox ID="CheckBox1" Text="1" runat="server" />
<asp:CheckBox ID="CheckBox2" Text="2" runat="server" />
<asp:CheckBox ID="CheckBox3" Text="3" runat="server" />
<asp:CheckBox ID="CheckBox4" Text="4" runat="server" />

我需要的是过滤"MyList"

我做了以下事情:

if (CheckBox1.Checked && !CheckBox2.Checked && !CheckBox3.Checked && !CheckBox4.Checked)
{
    MyList = MyList.Where(a => a.Avg < 2);
}
else if (CheckBox2.Checked && !CheckBox1.Checked && !CheckBox3.Checked && !CheckBox4.Checked)
{
    MyList = MyList.Where(a => a.Avg >= 2 && a.Avg < 3);
}
else if (CheckBox3.Checked && !CheckBox2.Checked && !CheckBox1.Checked && !CheckBox4.Checked)
{
    MyList = MyList.Where(a => a.Avg >= 3 && a.Avg < 6);
}
else if (CheckBox4.Checked && !CheckBox2.Checked && !CheckBox3.Checked && !CheckBox1.Checked)
{
    MyList = MyList.Where(a => a.Avg >= 6);
}

如果我一次只需要选中一个复选框,这很好,但如果我想一次选中2个或3个呢。

创建这么多如果条件不是最好的解决方案,我需要通过linq如果可能的

我正在做的是创建一个新的MyList,并将过滤后的MyList"插入"其中,但结果并不好。

提前谢谢。

C#使用Where(Linq)过滤具有四个条件的列表

反之亦然。测试每个复选框。如果选中,请删除由该复选框表示的条目。或者最好是那些没有代表性的人。因此,如果CheckBox1是而不是选中的,则取那些不是<2,这意味着它们>=2。

    if (!CheckBox1.Checked)
    {
        MyList = MyList.Where(a => a.Avg >= 2);
    }
    if (!CheckBox2.Checked)
    {
        MyList = MyList.Where(a => a.Avg < 2 || a.Avg >= 3);
    }
    if (!CheckBox3.Checked)
    {
        MyList = MyList.Where(a => a.Avg < 3 || a.Avg >= 6);
    }
    if (!CheckBox4.Checked)
    {
        MyList = MyList.Where(a => a.Avg < 6);
    }

在下一步中,您应该预先计算平均值,这样该函数就不会被调用太多次。例如,构建元组(row,average),然后过滤平均值,并通过从元组中提取行来返回行。

您的问题吸引了我使用字典找到解决方案。这将把你的代码留给像这样简单的两行(好吧,也需要一个简单的函数)

int index = CreateIndexFromCheckboxSelected();
var result = MyList.Where(x => dict[index].Invoke(x));

为了达到这个解决方案,您需要构建一个以数字键和Func为值的Dictionary。

数字键是与布尔逻辑相关的各种复选框的字节和,其中checkBox1表示位置1的位,checkbox2表示位置2的位,依此类推…

Func部分是应用于sqGetDataRow元素列表的where子句所需的lambda表达式

该字典中需要16个条目,4个复选框的可能组合各有一个条目,每个条目都包含要在where子句中使用的lambda表达式,以提取所需的spGetDataRow元素。

Dictionary<int, Func<spGetDataRow,bool>> dict = new Dictionary<int, Func<spGetDataRow, bool>>()
{
    {0, (spGetDataRow a) => true},                      // No checkboxes checked return all
    {1, (spGetDataRow a) => a.Avg < 2},                 // Only checkbox1 checked
    {2, (spGetDataRow a) => a.Avg >= 2 && a.Avg < 3},   // Only checkbox2 checked
    {3, (spGetDataRow a) => a.Avg ????},                // CheckBox1 AND Checkbox2 checked
    {4, (spGetDataRow a) => a.Avg >= 3 && a.Avg < 6},   // CheckBox3 checked
    {5, (spGetDataRow a) => a.Avg ????},                // CheckBox3 + ChecBox1 checked
    {6, (spGetDataRow a) =>  a.Avg >= 2 && a.Avg < 6},  // CheckBox3 + CheckBox2 checked
    {7, (spGetDataRow a) => a.Avg ????},                // CheckBox3 + CheckBox2 + CheckBox1 checked    
    {8, (spGetDataRow a) => a.Avg >= 6},                // CheckBox4 checked
    {9, (spGetDataRow a) => a.Avg ????},                // CheckBox4 + CheckBox1 checked
    {10, (spGetDataRow a) => a.Avg ????},               // CheckBox4 + CheckBox2 checked
    {11, (spGetDataRow a) => a.Avg ????},               // CheckBox4 + CheckBox2 + CheckBox1 checked    
    {12, (spGetDataRow a) => a.Avg ????},               // CheckBox4 + CheckBox3 checked
    {13, (spGetDataRow a) => a.Avg ????},               // CheckBox4 + CheckBox3 + CheckBox1 checked
    {14, (spGetDataRow a) => a.Avg ????},               // CheckBox4 + CheckBox3 + CheckBox2 checked
    {15, (spGetDataRow a) => true}                      // All checkboxes selected return all
};

上面的例子只包含我可以从你的问题中提取的信息的正确lambda,但正如你所看到的,用你需要的复选框的各种组合的正确的lambda替换占位符lambda只是一个问题。

为了完成这个例子,只缺少一块,但这是一个微不足道的

public int CreateIndexFromCheckboxSelected()
{
    int chk1 = (CheckBox1.Checked ? 1 : 0);
    int chk2 = (CheckBox2.Checked ? 2 : 0);
    int chk3 = (CheckBox3.Checked ? 4 : 0);
    int chk4 = (CheckBox4.Checked ? 8 : 0);
    return (chk1 + chk2 + chk3 + chk4);
}