基于多个条件和多个值(未知值数)筛选列表
本文关键字:未知 筛选 列表 条件 于多个 | 更新日期: 2023-09-27 18:21:58
我有一个类User
:
public class User{
// some properties
public string Name { get; set; }
public int PerfLoc { get; set; }
public bool Active { get; set; }
// constructor would follow ..
}
我有一个类别PerfLoc
:
public class PerfLoc{
// some properties
public string Number { get; set; }
// constructor would follow ..
}
我有一个用户列表List<User> myUsers
和一个列表List<PerfLoc> myPerfLoc
。现在我想找到所有具有特定PerfLoc
的myUsers
用户。所以我在myUsers
和myPerfLoc
中都有多个值。现在的练习是做一场比赛。我想了一些像这样的pseudeo代码:
List<User> filteredUser = new List<User> ();
foreach(PerfLoc currentPerfLoc in myPerfLoc){
filteredUser += myUsers.Any(u => u.PerfLoc == currentPerfLoc.Number);
}
filteredUser = filterUser.Any(u => u.Active = true);
filteredUser.Sort();
在这里,我会在PerfLoc
和Active
(=多个标准)之后排序,也会在多个值(PerfLoc.Number
的列表)之后排序。我从中看到了一些,其中,selectLINQ表达式,并认为我的上述方法可以用更短的方式表达。你会怎么表达?
您可以使用LINQ中的联接语句来完成此操作。与SQL类似,您可以将两个列表放在一起,并在属性或表达式上进行匹配。您也可以使用orderby进行排序。
以下是对匹配PerfLocs列表的活动用户的基本检查:
var filteredUser = from u in myUsers
join p in myPerfLocs on u.PerfLoc equals p.Number.ToString()
where u.Active == true
orderby u // or u.Name if you need to
select u;
由于您有条件地检查Active state和myPerfLocs,可能有一种方法可以在单个子句中进行检查,但它看起来会很混乱,所以我无论如何都会将其作为单独的检查保留-更短并不总是更干净。你可以创建一个结果IEnumerable,然后根据需要进行过滤:
bool checkActive = true;
// set up result list - variable needs to be IEnumerable<User>, not List<User>
var filteredUser = myUsers.AsEnumerable();
// add Active check if necessary
if (checkActive)
{
filteredUser = filteredUser.Where(u => u.Active);
}
// check against PerfLoc list if necessary
if (myPerfLocs.Any())
{
filteredUser = from u in filteredUser
join p in myPerfLocs on u.PerfLoc equals p.Number.ToString()
select u;
}
filteredUser = filteredUser.OrderBy(u => u); // or (u => u.Name) etc if you want
请参阅https://dotnetfiddle.net/hrnNmJ对于工作样品。
您可以使用Join
。但请注意,在您提供的代码中,User.PerfLoc
是int
,PerfLoc.Number
是string
。如果真的是这样的话,那么你必须在下面的代码中添加一个转换。
var filteredUser = myUsers.Where(u => u.Active)
.Join(myPerfLoc, (u) => u.PerfLoc,
(p) => p.Number,
(u, p) => u);