在ABAddressBook中获取重复的电话号码时提高性能

时间:2013-02-06 23:25:43

标签: iphone ios xamarin.ios abaddressbook

'正在使用iPhone APP获取重复的手机号码我已经制作了代码,但性能非常糟糕并需要时间。这是我的代码:

    OrderedDictionary persons = new OrderedDictionary ();
    ABAddressBook ab = new ABAddressBook ();

    foreach (ABPerson p in ab.GetPeople()) {

            foreach (var phoneNumber in p.GetPhones().GetValues()) {
                var duplicates = SearchByPhoneNumber (ab, phoneNumber);
                if (duplicates.Count > 1) {
                    if (!persons.Contains (phoneNumber)) {
                        persons.Add (phoneNumber, duplicates);
                    }
                }

            }
        }


    List<ABPerson> SearchByPhoneNumber ( ABAddressBook ab, string phoneNumber)
{
        List<ABPerson> duplicatepeople = new List<ABPerson> ();
        phoneNumber = Regex.Replace (phoneNumber, "[^0-9]", "");


        var people = ab.Where(x=> x is ABPerson).Cast<ABPerson>().Where(x=> x.GetPhones()
                                                                        .Where(p=> Regex.Replace(p.Value,"[^0-9]", "")==phoneNumber || phoneNumber ==Regex.Replace(p.Value,"[^0-9]", "")).Count() > 0).ToArray();

        foreach(ABPerson person in people)
        {
            if( duplicatepeople.Intersect(person.GetRelatedNames().Cast<ABPerson>()).Count() <= 0)
            {
                duplicatepeople.Add(person);
            }

        }

        return duplicatepeople;
    }

1 个答案:

答案 0 :(得分:0)

我没有时间检查两者之间的时间,但我确实注意到你在地址簿号码上多次迭代(对于每个电话号码,你再次在列表中迭代每个.Where)。另外我注意到你在循环中多次为每个电话号码执行相同的正则表达式。

这可能不完全符合您的需求,但它确实在我的地址簿中找到了重复内容并且速度不是很慢。

ABAddressBook ab = new ABAddressBook();

// flatten out the list of all phone numbers and perform the regEx just once for each phone number
var processedList = new List<Tuple<string, ABPerson>>();
foreach (ABPerson p in ab.GetPeople()) 
{
    foreach (var phoneNumber in p.GetPhones().GetValues()) 
    {
        processedList.Add(new Tuple<string, ABPerson>(Regex.Replace (phoneNumber, "[^0-9]", ""), p));
    }
}

var duplicates = (from person in processedList
    group person by person.Item1 into g
    where g.Count() > 1
    select new { PhoneNumber = g.Key, Person = g }).ToList();

foreach (var d in duplicates)
{
    Console.WriteLine("{0}  {1}", d.PhoneNumber, d.Person.Count());
    foreach (var p in d.Person)
    {
        Console.WriteLine(p.Item2.FirstName);
    }
}

我希望这会有所帮助。