I'm trying to find a way to populate a Map<Id,List<SObject>> Where the key is an Id of a different SObject. Specifically, I'd like to return campaign members associated with contacts at an account with an Opportunity, and then use the AccountId as my map key. I'd then like to be able to sort that list based on a custom field value.

This thread here seems to be looking to do the same sort of thing, and I gather that I'll need to populate this Map myself with a loop. As a basic structure this probably looks something like this:

trigger CampaignMembers on Opportunity (after insert){
    Set<Id> accIds = new Set<Id>();

    for(Opportunity o : Trigger.new){

    Map<Id,List<CampaignMember>> accountCampaignMap = new Map<Id,List<CampaignMember>>();

    for(CampaignMember cm : [SELECT Id, CampaignId, AccountID_Formula__c FROM CampaignMember WHERE AccountID_Formula__c = :accIds]){
        //somehow populate Map
    //do other stuff

This documentation also seems to suggest that if I need to create a wrapper class in order to support a custom sort, which I'd rather avoid, if possible.

To implement a custom sort order for sObjects in lists, create a wrapper class for the sObject and implement the Comparable interface. The wrapper class contains the sObject in question and implements the compareTo method, in which you specify the sort logic.

Could I get around this by including an ORDER BY in my SOQL and then doing something like this:

for(CampaignMember cm : campaignMembers){

so that I'd be sorting it by default since my List that I'm looping through is already pre-sorted? Thanks in advance--it's been a long day...

  • Are you trying to group or sort? It's hard to follow what exactly you're after since your problem statement kind of meanders between a few points.
    – Adrian Larson
    Aug 25, 2016 at 22:16
  • 1
    Todd, while I agree with Adrian's comment, I think you've answered your own question there. Your code (both parts) will create a Map, where the key is an accountId and the values are lists of CampaignMembers. The Records will be sorted in the order of which you add them to the list so, if the records are sorted in your SoQL, then your lists will be too Aug 25, 2016 at 22:17

1 Answer 1


A generic pattern for the sort of logic I think you are aiming to create is this:

for (CampaignMember cm : [
        SELECT Id, CampaignId, AccountID_Formula__c
        FROM CampaignMember
        WHERE AccountID_Formula__c = :accIds
        ORDER BY Name
    List<CampaignMember> l = accountCampaignMap.get(cm.AccountID_Formula__c);
    if (l == null) {
        l = new List<CampaignMember>();
        accountCampaignMap.put(cm.AccountID_Formula__c, l);

This will result in each list being in the order of the CampaignMember.Name.

You must log in to answer this question.

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