1

I am trying to make a Utility method that takes a List<Contact> parameter and compares the Contact.Email it to a custom list of URLS. I need to know if the Contact.Email matches any URL in my list even though the URL string is not a complete domain; meaning instead of domain.com it would just be domain

Not sure how I would do this comparisson, but I know I'm suppose to avoid nested loops so I'm attempting something like this so far:

public static List<Contact> compareThisList (List<Contact> contact_list){
    List<Contact> return_list = new List<Contact>();
    Map<URL__c,Domains__c> domain_list = new Map<URL__c,Domains__c>([SELECT Id, URL__c FROM Domains__c]);

    for(Contact c : contact_list){
        //if c.Email.contains() a partial map to domain_list.anykey then add to return_list
        // Not sure how since Email would be name@domain.com but domain_list keys would just have domain
    }
}
  • You can use nested loops. However, you always want to avoid SOQL inside of for loops. Or nested For loops which can invoke governor limit functions. salesforce.com/us/developer/docs/apexcode/Content/… . So if you iterate over your collection of Contacts and peform a contains() operation on the String you are probably safe. – CoryCowgill Jan 27 '15 at 21:08
1

I would probably split this out into two methods and use upper/lower case to avoid regular expressions, though they are certainly a viable alternative.

public with sharing class ContactServices
{
    public Set<String> domains
    {
        get
        {
            if (domains == null)
            {
                domains = new Set<String>();
                for (Domains__c domain : [SELECT URL__c FROM Domains__c])
                {
                    domains.add(domain.URL__c);
                }
            }
            return domains;
        }
        private set;
    }

    public List<Contact> matchesAnyDomain(List<Contact> candidates)
    {
        List<Contact> matches = new List<Contact>();
        for (Contact candidate : candidates)
        {
            if (matchesAnyDomain(candidate))
                matches.add(candidate);
        }
        return matches;
    }
    public Boolean matchesAnyDomain(Contact candidate)
    {
        for (String domain : domains)
        {
            if (candidate.Email.containsIgnoreCase(domain)) return true;
        }
        return false;
    }
}
  • So this response doesn't include my SOQL statement which I need because I'm not storing domain list in the class. And although this approach is interesting re-factoring the method like that, it is still a loop within a loop technically. @CoryCowgill commented that it might not be a big deal as my question suggest but is that to say then that there is no way to avoid that here? – Xtremefaith Jan 28 '15 at 0:33
  • You could incorporate that query into the domains property. The important part is that it is a Set<String> so you can check contains. I don't think you are going to avoid nested loops given your requirements, but your inner loop (over domains) is fairly limited, I would imagine. – Adrian Larson Jan 28 '15 at 0:59
  • note there is now a containsIgnorecase() method on String class – cropredy Jan 28 '15 at 1:14
  • Good to know. Of course it is not in the documentation and since I could not remember offhand, I did not include it. – Adrian Larson Jan 28 '15 at 1:22
  • but it is in the doc - salesforce.com/us/developer/docs/apexcode/index.htm – cropredy Jan 28 '15 at 1:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.