我有一个列表(ios联系人),我需要根据以匹配字符串开头的名字,姓氏和电子邮件进行过滤。我有大约5000个联系人,目前大约需要2秒来过滤结果。这是我的代码。
var personList = people.FindAll (p =>
(p.LastName != null && p.LastName.IndexOf (findstr, StringComparison.OrdinalIgnoreCase) == 0) || (p.FirstName != null && p.FirstName.IndexOf (findstr, StringComparison.OrdinalIgnoreCase) == 0
|| (p.GetEmails ().ToList ().Count > 0 && (p.GetEmails ().ToList ().FindAll (e => e.Value.IndexOf (findstr, StringComparison.OrdinalIgnoreCase) == 0).Count > 0)))
);
有人能建议更快的方法吗?感谢
答案 0 :(得分:0)
取代FindAll
,并调用ToList
然后调用Count
,请使用:
var personList = people.Where(p => (p.LastName != null
&& p.LastName.IndexOf(findstr, StringComparison.OrdinalIgnoreCase) == 0)
|| (
p.FirstName != null && p.FirstName.IndexOf(findstr, StringComparison.OrdinalIgnoreCase) == 0
|| (p.GetEmails().Count > 0 && (p.GetEmails()
.Where(e =>
e.Value.IndexOf(findstr, StringComparison.OrdinalIgnoreCase) == 0).Count > 0))
));
答案 1 :(得分:0)
使用IndexOf(..) == 0
进行比较与询问该字符串(姓名,姓氏或电子邮件)是否以给定的findstr
开头相同。如果您想要知道字符串是否包含de findstr
,请使用String.Contains
或IndexOf(..) != -1
我还会将这些谓词与代码清晰度分开,如下所示:
Func<string, bool> filter = s => !String.IsNullOrWhiteSpace(s) && s.StartsWith(findstr, StringComparison.OrdinalIgnoreCase);
var personList = people.Where(p => filter(p.FistName)
|| filter(p.LastName)
|| p.GetEmails().Select(e => e.Value).Any(filter));
现在,如果你想要,你可以并行完成:
var personList = people.AsParallel().
Where(p => filter(p.FistName)
|| filter(p.LastName)
|| p.GetEmails().Select(e => e.Value).Any(filter));
答案 2 :(得分:0)
您可以使用:
Any()
代替ToList().Count > 0
First()
然后检查它是否与条件匹配,而不是IndexOf (findstr, StringComparison.OrdinalIgnoreCase) == 0
您可以找到队列的完整列表here。