更快速地根据条件过滤对象列表到另一个列表

时间:2014-06-17 13:35:05

标签: c# performance linq xamarin.ios

我有一个列表(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)))

                    );

有人能建议更快的方法吗?感谢

3 个答案:

答案 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.ContainsIndexOf(..) != -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