【问题标题】:C# using Where (Linq) to filter a list with four conditionC# 使用 Where (Linq) 过滤具有四个条件的列表
【发布时间】:2014-10-22 08:25:18
【问题描述】:

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

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,并将过滤后的“连接”到其中,但结果并不好。

提前谢谢你。

【问题讨论】:

  • 能否请您发布您想要放置在过滤器中的要求。例如,当 Checkbox1 是唯一选中的复选框时,然后 a.Avg&lt;2 等?谢谢
  • 那么,如果(比如说)复选框 2 和 3 被选中,您会想要产生什么效果?如果什么都没检查呢?
  • @JonSkeet: 如果什么都没有检查,则显示全部,如果所有检查也显示全部
  • @MohamadY.Dbouk 但是在选中 2 和 3 时显示,什么都没有?
  • @Vladimirs:如果选中 2 和 3:where 条件如下:MyList.Where(a => a.Avg >= 2 && a.Avg

标签: c# asp.net linq dataset ienumerable


【解决方案1】:

反之亦然。测试每个复选框。如果选中,则删除此复选框表示的条目。或者最好选择那些没有代表的。因此,如果 CheckBox1 被 not 选中,则选择那些 not =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) 然后过滤平均值并通过从元组中提取它们来取回行。

【讨论】:

  • 添加“||”修理它。谢谢!
【解决方案2】:

您的问题激发了我使用字典找到解决方案的兴趣。这将使您的代码像这样简单的两行(也需要一个简单的函数)

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

要实现此解决方案,您需要构建一个带有数字键和 Func 作为值的字典。

数字键是各种复选框的字节总和,其中 checkBox1 表示位置 1 的位,checkBox2 表示位置 2 的位,依此类推......

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

您需要此字典中的 16 个条目,每个条目对应 4 个复选框的可能组合,每个条目包含要在 where 子句中用于提取所需 spGetDataRow 元素的 lambda 表达式。

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);
}

【讨论】:

    猜你喜欢
    • 2019-08-25
    • 2023-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-25
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多