0

I'm working on iPhone APP that getting the duplicate phone Numbers i already made the code but the performance is so bad and taking time .here's my code:

    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;
    }
Emil
  • 7,220
  • 17
  • 76
  • 135

1 Answers1

0

I haven't had time to check timings between the two, but I did notice that you're iterating over the address book numbers multiple times (for each phone number you iterate over the list again with each .Where). Also I notice that you perform the same Regex for each phone number multiple times in the loops.

This might not be exactly to your needs, but it did find duplicates in my address book and wasn't too slow.

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);
    }
}

I hope this helps.

Greg Munn
  • 526
  • 2
  • 7