我有一个从数据库中获取的列表(使用数据集):
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,并将已过滤的一个'连接'到它中,但它并没有很好地结束。
提前谢谢你。
答案 0 :(得分:2)
反之亦然。测试每个复选框。如果未选中,请删除此复选框表示的条目。或者更好地选择那些没有代表的人。因此,如果CheckBox1 不选中,则选择不&lt; 2表示&gt; = 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);
}
在下一步中,您应该预先计算平均值,以便不会多次调用此函数。例如。构建元组(行,平均值)然后过滤平均值并通过从元组中提取行来获取行。
答案 1 :(得分:0)
你的问题让我很想找到一个使用词典的解决方案。这将使您的代码保持简单的两行(这也是一个简单的函数)
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);
}