[SalesForce] How to search for a string in a list of strings

I'm currently programming some pretty random things in my developer edition to try and get some practice in until my company gives me more apex projects. In my most recent project, I wanted to assign a user an account name based on their city. I don't know if there would ever a reason to actually use this, but hopefully someone can help anyway.

Right now, I have a bunch of "if-else" statements for each possibility. This isn't really an option unless there are only a few potential cities. So my thought was to store the cities and the potential account names in lists, then use an "if" statement to check strings against the list. However, I'm not sure how or if I can do that.

Here is the code. It's in very early stages and is very much conceptual.

public class ChainReactionUserClass {
@future public static void ChainReactionStart(set<ID> recordIDs){
    //Grab all required fields from user.  Essetial to test class running.
    list<user> users = [SELECT ID, Firstname, Lastname, email, name, username, street, city, state, postalcode, country,
                        UserRoleId, CommunityNickname, TimeZoneSidKey, LocaleSidKey, EmailEncodingKey, ProfileId,
                        LanguageLocaleKey 
                        FROM user
                        WHERE ID in :recordIDs];

    //creates a list with several potential account names
    list<string> accountName = new list<string>();
    accountName.add('South East');
    accountName.add('North East');
    accountName.add('North West');
    accountName.add('South West');

    //creates several lists to hold different strings for cities in different regions of the US
    list<string> cities = new list<string>();
    /*
    cities.add('Memphis');
    cities.add('Atlanta');
    cities.add('Boston');
    cities.add('Providence');
    cities.add('Seattle');
    cities.add('Portland');
    cities.add('Sante Fey');
    cities.add('Las Vegas');
    */        

    list<contact> contactInsert = new list<contact>();
    //cannot directly assign strings from a list, have to iterate through it using a for loop.
    for (User u: users){
        String String1 = u.city;

        for(String s : cities){
            if (cities.isEmpty()){
                system.debug('Cities list is empty');
            }
        }
        /* Need to find a way to query for string values in a list rather than hard code for each city
        if(String1 == 'Memphis'){system.debug(String1);}
        else if (String1 == 'Boston'){system.debug(String1);}
        else if (String1 == 'Seattle'){system.debug(String1);}
        else if (String1 == 'Atlanta'){system.debug(String1);}
        else if (String1 == 'Portland'){system.debug(String1);}
        else if (String1 == 'Las Vegas'){system.debug(String1);}
        else if (String1 == 'Sante Fey'){system.debug(String1);}
        else if (String1 == 'Providence'){system.debug(String1);}
        */
        Contact c = new Contact(
        FirstName = u.FirstName,
        LastName = u.LastName,
        MailingStreet = u.street,
        MailingCity = u.city,
        MailingState = u.state,
        MailingPostalCode = u.PostalCode,
        email = u.email);
        contactInsert.add(c);
        insert contactInsert;    
    }        
}}

Best Answer

The easiest way to implement that kind of lookup in code is with a Map.

Your code could look like this:

public class ChainReactionUserClass {
    @future public static void ChainReactionStart(set<ID> recordIDs){
        //Grab all required fields from user.  Essetial to test class running.
        list<user> users = [SELECT ID, Firstname, Lastname, email, name, username, street, city, state, postalcode, country,
                    UserRoleId, CommunityNickname, TimeZoneSidKey, LocaleSidKey, EmailEncodingKey, ProfileId,
                    LanguageLocaleKey 
                    FROM user
                    WHERE ID in :recordIDs];

        Map <String,String> regions = new Map <String,String> ('Boston' => 'Nort East', 'San Francisco' => 'South West'); // etc.

        list<contact> contactInsert = new list<contact>();

        for (User u: users){

            String region = regions.Get (u.City);

            Contact c = new Contact(
            FirstName = u.FirstName,
            LastName = u.LastName,
            MailingStreet = u.street,
            MailingCity = u.city,
            MailingState = u.state,
            MailingPostalCode = u.PostalCode,
            email = u.email,
            Region__c = region);
            contactInsert.add(c);
        }
        insert contactInsert;    
    }
}

The issue with this approach is that you're hard-coding your city-to-region relationships in your code. A better approach would be to create an object model that represents your city to region mapping, and query it inside your Apex. This way, your users can expand your city to region mapping outside code (just by point and click).

Edit: A few notes on your original code:

  • You were inserting contactInsert inside the for loop. It has to be inserted outside the loop, once you've populated the whole list; otherwise, you're using your DML limits very inefficiently.
  • You were checking for an empty cities list inside the for loop. The check needs to be done outside (although, depending on what your code does, it might not be necessary... the for will simply not iterate at all).