[英]FindAll in a c# List, but varying search terms
List<DTOeduevent> newList = new List<DTOeduevent>();
foreach (DTOeduevent e in eduList.FindAll(s =>
s.EventClassID.Equals(cla)
&& s.LocationID.Equals(loc)
&& s.EducatorID.Equals(edu)))
newList.Add(e);
cla, loc, edu can be (null or empty) or supplied with values-- cla,loc,edu可以为(null或为空)或提供值-
basically how can I simply return the original list (eduList) if cla, loc, edu are all null 基本上,如果cla,loc,edu全部为null,我如何简单地返回原始列表(eduList)
or search by loc, search by loc, edu, search by edu, cla -- etc........ 或按位置搜索,按位置搜索,edu,按edu搜索,cla等--........
my sample code only makes a new list if all 3 vars have values-- 我的示例代码仅在所有3个变量都具有值的情况下才创建新列表-
is there an elegant way to do this, without brute force if statements? 有没有一种优雅的方式来做到这一点,而无需强行使用if语句?
List<DTOeduevent> newList = eduList.FindAll(s =>
(cla == null || s.EventClassID.Equals(cla))
&& (loc == null || s.LocationID.Equals(loc))
&& (edu == null || s.EducatorID.Equals(edu)));
Assuming the values are Nullable value types or classes. 假设值是可为空的值类型或类。 If they're strings, you could replace cla == null
with String.IsNullOrEmpty(cla)
. 如果它们是字符串,则可以用String.IsNullOrEmpty(cla)
代替cla == null
。
IEnumerable<DTOeduevent> newList = eduList;
if (cla != null)
{
newList = newList.Where(s => s.EventClassID == cla);
}
if (loc != null)
{
newList = newList.Where(s => s.LocationID == loc);
}
if (edu != null)
{
newList = newList.Where(s => s.EducatorID == edu);
}
newList = newList.ToList();
Due to deferred execution, the Where
statements should all execute at once, when you call ToList
; 由于延迟执行,因此Where
调用ToList
时, Where
语句应全部立即执行。 it will only do one loop through the original list. 它只会在原始列表中进行一个循环。
I would personally lean towards something that encapsulated the logic of what you seem to be doing here: checking that a found id is equal to some search id. 我个人倾向于采用某种封装您似乎在这里做的逻辑的东西:检查找到的ID是否等于某些搜索ID。 The only wrinkle is how to get that check for null or empty in there first. 唯一的麻烦是如何首先获取在那里是否为空或空的检查。
One way to do that is by using a static extension method: 一种方法是使用静态扩展方法:
public static class DtoFilterExtensions
{
public static bool IsIdEqual(this string searchId, string foundId) {
Debug.Assert(!string.IsNullOrEmpty(foundId));
return !string.IsNullOrEmpty(searchId) && foundId.Equals(searchId);
}
}
I would also lean towards using LINQ and IEnumerable<> as Domenic does, even though you could make it work with List.FindAll just as easily. 我也倾向于像Domenic一样使用LINQ和IEnumerable <>,即使您可以轻松地将它与List.FindAll一起使用也是如此。 Here would be a sample usage: 这将是一个示例用法:
public void Filter(string cla, string loc, string edu) {
var startList = new List<DTOeduevent>();
var filteredList = startList
.Where(x => x.classId.IsIdEqual(cla) && x.locationId.IsIdEqual(loc) && x.educatorId.IsIdEqual(edu));
Show(filteredList.ToList());
}
In your own code of course you have got that start list either in a member variable or a parameter, and this assumes you have got some method like Show() where you want to do something with the filtered results. 当然,在您自己的代码中,您可以在成员变量或参数中获得该开始列表,并且假定您有某种类似于Show()的方法要对过滤后的结果进行处理。 You trigger the deferred execution then, as Domenic explained with the ToList call (which is of course another extension method provided as part of LINQ). 然后,您触发延迟执行,如Domenic在ToList调用中所述(当然,这是LINQ的一部分提供的另一种扩展方法)。
HTH, HTH,
Berryl Berryl
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.