I have a String extDB_Table__c.inputString__c that looks like this:


The ||| is meant to be a delimiter between whatever values are in the string (comes after every value, including the final one).

Values like SPN are all keys in a Map<String,String> transMap, where the values are translations to the equivalent spelling of the concept in a multi-select picklist, e.g.

ECON --> Economics
MTHS --> Math and Statistics
SPN --> Spanish
THE --> Theology

Sometimes I'll have another string Opportunity.MSP__c with a pre-existing value like Dance;Economics;Astronomy

I'd like to optimize two different operations:

  1. Building a semicolon-delimited string outputStringA full of the "translated" values like Math and Statistics;Economics;Spanish (when I know there's no Opportunity related to the extDB_Table__c record I'm processing and I have to create it)
  2. Building a semicolon-delimited string outputStringB that takes Opportunity.MSP__c into account and produces something like Dance;Economics;Astronomy;Math and Statistics;Spanish (order and redundancy of Economics not important as long it's not important when doing DML to multi-select picklists)

What Apex algorithms / code patterns would people suggest for building outputStringA and for building outputStringB as efficiently as possible? (I can think of a lot of ways to do it inefficiently...)

This is inside a loop through extDB_Table__c records. The delimiter pattern for extDB_Table__c.inputString__c is always the same; there is a branch inside the loop to determine whether I need to compute outputStringA or outputStringB.

  • 2
    No need to add Apex in the title. It's redundant, that's what tags are for and it's pretty clear in this context.
    – Adrian Larson
    Commented Apr 5, 2017 at 20:38

1 Answer 1


When dealing with multi-picklist fields, I've generally found the most sensible thing is to Split them into collections, then Join them once you've added all the members you want. I've made a few assumptions about the context of your situation.

public static void mergePicklist(extDB_Table__c tab, Opportunity opp)
    //Zero in the limit parameter removes trailing empty strings according to the documentation
    List<String> inputStringList = tab.InputString__c.Split('\\|\\|\\|', 0);
    Set<String> finalSet = new Set<String>();
    if (opp.MSP__c != null)
    for(String input : inputStringList)
    opp.MSP__c = String.join(new List<String>(finalSet), ';');
  • Thanks so much, @IllusiveBrian -- that is exactly what I'm talking about as far as functionality is concerned (I suppose I should have included something like this in my original question, so thank you). Leaving the question open for others' thoughts on performance optimization, though. Particularly in the outputStringA example, I keep wondering if there's an efficient way to treat extDB_Table__c.inputString__c as some sort of buffer--working from left to right through the string, replacing pieces directly as they're detected and then moving on.
    – k..
    Commented Apr 5, 2017 at 21:12
  • Working from your example: since i'll have separate code blocks handling cases when Opportunity exists or not, in the outputStringA case do you think it'd be any more efficient to do a traditional for loop to i<inputStringList.size(), do inputStringList[i]=transMap.get(inputStringList[i]), and join inputStringList itself after the loop?
    – k..
    Commented Apr 5, 2017 at 21:21
  • You might want to make sure you remove null or the empty string as there is a terminating delimiter.
    – Adrian Larson
    Commented Apr 5, 2017 at 22:25
  • @AdrianLarson I think setting the limit parameter to 0 should remove the last blank trailing string based on what the documentation for split says: developer.salesforce.com/docs/atlas.en-us.apexcode.meta/…, however I just noticed that overload when I was writing this answer so I've never tried it. Commented Apr 6, 2017 at 0:31
  • 1
    @k.. Strings are immutable, so you can't really use it the way you are suggesting. Even if they weren't, they are usually an array "under the hood" so adding characters in the middle means you have to push every character afterward further back. The problem with trying to figure out how to optimize a solution is that we need to know more about your expected data - if you have many duplicates, adding them to the set doesn't do anything, so the final join is against fewer elements. If you don't have many duplicates, your solution may be more efficient. Do you need a particular optimization? Commented Apr 6, 2017 at 3:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .