通过另一个过滤列表

时间:2012-12-17 22:33:43

标签: c# linq

我要求根据客户列表在过去x个月内没有预订任何作业来过滤客户列表。在我的代码中,我有两个列表,一个是我的客户端,另一个是今天和x个月之前过滤的作业列表,其目的是根据客户列表中未显示的ID过滤客户端。我尝试了以下方法:

filteredClients.Where(n => jobsToSearch.Count(j => j.Client == n.ClientID) == 0).ToList();

但我似乎得到了所有客户。我可以很容易地做一个foreach但这会严重减慢这个过程。如何有效地根据作业列表过滤客户列表?

3 个答案:

答案 0 :(得分:3)

你做错的主要原因是你没有将结果归还给某些东西。这就是为什么你的原创似乎保留所有客户。但我们仍然可以改进原文:

filteredClients = filteredClients.Where(n => !jobsToSearch.Any(j => j.Client == n.ClientId)).ToList();

这与.Count()解决方案之间的区别在于,.Any()可以在遇到第一个匹配时立即停止查看每个客户端的作业列表,因此它应该运行得更快一些。但我们还没有完成。我们可以通过将作业列表缩小到只有不同的客户来做得更好:

var badClients = jobsToSearch.Select(j => j.Client).Distinct().ToList();
filteredClients = filteredClients.Where(n => !badClients.Any(j => j == n.ClientId)).ToList();

甚至可能更好地使用HashSet,这可以使O(1)查找像Dcitionary。假设客户端ID是int:

 var badClients = new HashSet<int>(jobsToSearch.Select(j => j.Client));
 filteredClients = filteredClients.Where(n => !badClients.Contains(n.ClientId)).ToList();

最后一个选项是否表现更好取决于有作业的客户端数量......如果列表很短,.Distinct()可能仍会做得更好。

最后,我通常不建议像这样调用.ToList()。尽可能地保存实际上实现List,Array或集合类型直到最后一刻,并且尽可能长时间地保持它为Enumerable。

答案 1 :(得分:1)

你有没有考虑过使用“groupby”?

没有检查语法和编写代码(havnt vs available atm):

var groupedJobs = jobsearch.GroupBy(job => job.Client);
var itemsWithJobs = filteredList.Where(item => groupedJobs.ContainsKey(item.ClientID));

我明天早上可以查看语法。

最大的优点是,你已经建立了一个Dictonary,它在搜索速度要快得多。而不是迭代列表。

答案 2 :(得分:0)

过滤in IdList;

的客户
List1.Where(x=> IdList.Contains(x.ClientId));

过滤not in IdList;

的客户
List1.Where(x=> !IdList.Contains(x.ClientId));
相关问题