根据多个条件和多个值(未知数量的值)过滤列表

时间:2014-09-16 10:01:37

标签: c# linq

我有一个班级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。现在,我想查找具有特定myUsers的{​​{1}}的所有用户。因此,PerfLoc中有多个值,myUsers中有多个值。现在的练习是做一场比赛。我想到了某种像这样的pseudeo代码:

myPerfLoc

在这里,我已经在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列表)之后进行了排序。我看到了一些 from,where,选择 LINQ表达式,并认为我的上述方法可以用更短的方式表达。你会怎么表达这个?

2 个答案:

答案 0 :(得分:1)

您可以使用Join。但请注意,您提供的代码User.PerfLocintPerfLoc.Numberstring。如果确实如此,那么您必须在下面的代码中添加转换。

var filteredUser = myUsers.Where(u => u.Active)
                          .Join(myPerfLoc, (u) => u.PerfLoc, 
                                           (p) => p.Number, 
                                           (u, p) => u);

答案 1 :(得分:1)

您可以使用LINQ中的join语句执行此操作。与SQL类似,您将两个列表放在一起,并在属性或表达式上匹配它们。您还可以使用orderby进行排序。

以下是匹配PerfLocs列表的Active Users的基本检查:

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;

当您有条件地检查活动状态和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