1

I have a list of AccountTeamMember records coming into a trigger handler class. From this list, I need to create a Map where each item is a key with the unique account ID based on the AccountTeamMember.AccountId field and then a value with a list of AccountTeamMember records that are for that account.

Example:
List of ATM records

  1. AtmID=100,AccountID=A001,UserId,U001
  2. AtmID=101,AccountID=A001,UserId,U002
  3. AtmID=102,AccountID=A002,UserId,U003
  4. AtmID=103,AccountID=A002,UserId,U004
  5. AtmID=104,AccountID=A003,UserId,U005

Map of Account IDs and List of ATM records

  1. AccountID=A001, <AtmID=100, AtmId=101>
  2. AccountID=A002, <AtmID=102, AtmId=103>
  3. AccountID=A003, <AtmID=104>

How would I could about creating this Map with Apex?

1 Answer 1

1

That's just a map of lists:

Map<Id, List<AccountTeamMember>> atmByAcctId = new Map<Id, List<AccountTeamMember>>();
for(AccountTeamMember record: someAtmList) {
  AccountTeamMember[] atmListForAcct = atmByAcctId.get(record.AccountId);
  if(atmListForAcct == null) {
    atmByAcctId.put(record.AccountId, atmListForAcct = new AccountTeamMember[0]);
  }
  atmListForAcct.add(record);
}

You'll want to remember this pattern, it's really common for many bulkification tasks.

Another common form you may find online reads like this:

Map<Id, List<AccountTeamMember>> atmByAcctId = new Map<Id, List<AccountTeamMember>>();
for(AccountTeamMember record: someAtmList) {
  if (!atmByAcctId.containsKey(record.Id)) { 
    atmByAcctId.put(record.Id, new AccountTeamMember[0]);
  }
  atmByAcctId.get(record.Id).add(record);
}

Some people prefer this form, but it is relatively slow and inefficient, as I talk about in more detail in this answer.

In fact, it's so common, that I've used something like this as a generic method:

 public static Map<Object, List<sObject>> mapRecordsByField(sObject[] records, sObjectField field) {
   Map<Object, List<sObject>> results = new Map<Object, List<sObject>>();
   for(sObject record: records) {
     Object key = record.get(field);
     sObject[] recordsByValue = results.get(key);
     if(recordsByValue == null) {
       results.put(key, recordsByValue = new sObject[0]);
     }
     recordsByValue.add(record);
   }
   return results;
}
6
  • could you pls share documentation about the recordsByValue = new sObject[0] i see it for the first time and can't wrap my head around.
    – Damecek
    Aug 9, 2021 at 13:38
  • 1
    @Damecek assignment to a variable can then be used again. Consider this: String a, b; a = b = 'Hello World'; We assign 'Hello World' to b, and then assign it to a. In other words, that line of code is shorthand for recordsByValue = new sObject[0]; results.put(key, recordsByValue);
    – sfdcfox
    Aug 9, 2021 at 13:47
  • thanks and that part new sObject[0]? i understand that it allocates a new list with first item being the record? but how does the compiler figures out that we want exactly the record variable and not some other within the scope?
    – Damecek
    Aug 9, 2021 at 13:56
  • 1
    @Damecek We're creating a new, empty list of type sObject. You can also write this as new sObject[] {}, new List<sObject>(), new List<SObject>{}, or new List<sObject>(0). I write it as new sObject[0]; as a personal preference (I come from a C/C++/Java background), but you can use whatever form you like best. The form I use is the shortest of all of them, and even though I type fast, I prefer to write shorter code on average.
    – sfdcfox
    Aug 9, 2021 at 14:00
  • Thanks, that was what i wanted to know.
    – Damecek
    Aug 9, 2021 at 14:03

You must log in to answer this question.

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