Is it possible to have a Map (or other collection) of sObjects list, keyed by one lookup field of the same sObject.

Something like Maps of sObjects (below code doesn't works):

Map<Id, List<Custom__c>> itemsMap = new Map<Id, List<Custom__c>>([SELECT Lookup_To_Custom__r.Id, Name FROM Custom__c]);

Note: this gives the following error Invalid initial type LIST<Custom__c> for MAP<Id,LIST<Custom__c>>

Were the Idin Map<Id, List<Custom__c>> is a reference to the Lookup_To_Custom__r.Id field.


The special map constructor only handles the case of creating a map where the key is the ID and the value is the SObject.

To do what I think you want to do requires a loop:

Map<Id, List<Custom__c>> m = new  Map<Id, List<Custom__c>>();
for (Custom__c c : [
        SELECT Lookup_To_Custom__c, Id, Name
        FROM Custom__c
        WHERE Lookup_To_Custom__c != null
        ORDER BY Name
        ]) {
    List<Custom__c> l = m.get(c.Lookup_To_Custom__c);
    if (l == null) {
        l = new List<Custom__c>();
        m.put(c.Lookup_To_Custom__c, l);

Note that using the foreign key field Lookup_To_Custom__c is a little more direct than going through the reference and taking the ID Lookup_To_Custom__r.Id.

| improve this answer | |

This is certainly possible. You just need to build the map yourself instead of trying to create it form a a single query.

As an example lets say we have a custom lookup on the contact record to another contact, say 'Emergency Contact'. Its possible that a person is listed as the emergency contact for more 1 person, so we could create a map where the key is the contact id, and the value is actually a list of contacts in which they are the emergency contact for.

Obviously this is a bit different from your case, but the same idea and you should easily be able to adjust the code for your scenario.

Map<Id, List<Contact>> conMap = new Map<Id, List<Contact>>();
for(Contact parent : [Select Id, Name, (Select Id, Name From EmergencyContacts__r) From Contact]) {
    conMap.put(parent.Id, new list<Contact>());
    for(Contact child : parent.EmergencyContacts__r){
system.debug('My Map: ' + conMap);

You now have a map where a contact Id is the key, and a list of contacts that person is the emergency contact for is the value.

Hope that helps


Thinking about it more, you could likely make trim this down a bit more and just do this as well.

Map<Id, List<Contact>> conMap = new Map<Id, List<Contact>>();
for(Contact parent : [Select Id, Name, (Select Id, Name From EmergencyContacts) From Contact]) {
    conMap.put(parent.Id, parent.EmergencyContacts__r);

system.debug('My Map: ' + conMap);
| improve this answer | |
  • I think the case in the question is a self-reference similar the Account.ParentId. – Keith C Jul 31 '14 at 17:56
  • My example is a self reference as well. I just didn't quite understand the use case and his example, which is why I did it in another context. Am i misunderstanding the question? – Chris Duncombe Jul 31 '14 at 17:59
  • Sorry I was put off by seeing Select Id, Name From EmergencyContacts rather than Select Id, Name From EmergencyContacts__r. Your solution is sneakier than mine :). – Keith C Jul 31 '14 at 18:03
  • Ahhhh, yes that was my mistake, good catch. Fixed that. Both our answers are right, just a bit of a different twist on each :) – Chris Duncombe Jul 31 '14 at 18:10
  • I'm really struggling to accept an answer, I think I'm going with @KeithC 's answer, since his practically worked on copy - paste for my use case (I think I could have elaborated a bit more), but thank both of you. – Jose Jul 31 '14 at 18:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.