Apex 

The best Collection Helper method that Salesforce forgot

How often does it happen that you’d just need to extract one field from a collection, record by record, value by value, and pack the results into a separate list? And how many times of it do you repeat, copy-paste, or even create the same old lines of code from scratch, thinking there must be a better solution out there?

Well, there is now. Salesforce just might have forgotten about it in their Apex Recipes CollectionUtils. which enables you to extract basically anything from a given list of sObjects, except for a simple list of field values.

We’re happy to help out with the generateStringListFromSObjectList() method, for which you’ll need the following 4 parameters:

  • List<sObject> listToExtractFrom
    This is your list of records – it doesn’t have to be explicitly converted into a List<sObject> before. You can as well pass a List<Account> or List<CustomObject__c>.
  • String fieldAPIName
    The added value here is that fieldAPIName can contain a relational field that’s one or multiple levels away, it just needs to be queried in the List<sObject> that’s passed to the method. That field can be denoted as you’d reference it in Apex or SOQL – if you pass a List<Contact> for example, you can extract ‘Account.Name’.
  • Boolean blankCheck
    If true, nulls are excluded from the result, otherwise included.
  • Boolean uniqueCheck
    If true, repetitive values will only be returned once, otherwise as often as they occur.

Now here’s our little gem, ready to be distributed across the globe:

public without sharing class CollectionUtils {
 
    /* { Apex Recipes Code here } */

    public static List<String> generateStringListFromSObjectList(List<sObject> listToExtractFrom, String fieldAPIName, Boolean blankCheck, Boolean uniqueCheck) {
        List<String> listToReturn = new List<String>();
        if(String.isNotBlank(fieldAPIName)){
            List<String> fieldNameSplit = fieldAPIName.split('\\.');
            for(SObject mySObject : listToExtractFrom){
                // Retrieving Field Name
                String fieldValueFound;
                Integer fieldNameSplitSize = fieldNameSplit.size();
                if(fieldNameSplitSize > 1){
                    // Multiple elements: Work down the cascade
                    sObject auxiliarySObject;
                    for(Integer i = 0; i < fieldNameSplitSize; i++){
                        // First element: Initiate officeFieldNameFound
                        if(i == 0){
                            auxiliarySObject = mySObject?.getSObject(fieldNameSplit[i]);
                        // Neither first nor last element: Retrieve the next SObject level
                        } else if(i > 0 && i < fieldNameSplitSize - 1){
                            auxiliarySObject = auxiliarySObject?.getSObject(fieldNameSplit[i]);
                        // Last Element: Get the field
                        } else if(i == fieldNameSplitSize - 1) {
                            fieldValueFound = (String) auxiliarySObject?.get(fieldNameSplit[i]);
                        }
                    }
                } else {
                    fieldValueFound = (String) mySObject?.get(fieldNameSplit[0]);
                }
                // Either we do not do a blank check, or we do a blank check and the string to be checked is not blank
                if(!blankCheck || (blankCheck && String.isNotBlank(fieldValueFound))){
                    // Either we do not do an unique check, or we do an unique check and the value is unique
                    if(!uniqueCheck || (uniqueCheck && !listToReturn.contains(fieldValueFound))){
                        listToReturn.add(String.valueOf(fieldValueFound));
                    }
                }
            }
        }
        return listToReturn;
    }

}

Leave a Reply

Your email address will not be published. Required fields are marked *