4

I have a map which has more then one entry for each key value, how can I iterate through just those records for a particular key value. I don't want to do the following which iterates through the whole set, but just want to iterate through those for a particular key value, struggling to find the right syntax - probably missing something straightforward!

Map<id,List<ERP_Customer__c>> acctErpMap = new Map<id,List<ERP_Customer__c>>();

// code to put values in map to go here ... 

for (id key : acctErpMap.keyset())  
{  
    System.debug(logginglevel.INFO, 'PersonAccount DEBUG: MAP key = ' + key);  
    System.debug(logginglevel.INFO, 'PersonAccount DEBUG: MAP value = ' + acctErpMap.get(key));         
}

Following the help given by those who responded to the call I re-coded as per following:
1. A map of lists has been created.
2. The id of the map has therefore been able to be kept unique
3. The code now posted below shows:
(a) Setting up and populating the map.
(b) Reading back through the map.

/*****************************************************************
    Note: ERP_Customer__c is a child of the Account object.
    Create a map, acctErpMap, of lists as follows:
******************************************************************/ 
Map<id,List<ERP_Customer__c>> acctErpMap = new Map<id,List<ERP_Customer__c>>();
// Create an empty ERP list for each account record. 
For (Account acc : accList) 
{ 
    acctErpMap.put(acc.id, new List<ERP_Customer__c>());
}

//    Populate ERP_Customer__c list for each account being processed                 
for (ERP_Customer__c ERPChild : ERPFullList)
{
    acctErpMap.get(ERPChild.PersonAccount__c).add(ERPChild);
}

// Loop through accounts.
For (Account acc : accList)
{ 
    // Logic removed for purpose of post.
    // ...

    // Loop through ERP_Customer__c for this Account
    for (ERP_Customer__c ERPChild : acctErpMap.get(acc.id))
    {      
        // Logic removed for purpose of post...
        // ...
    }               
}
  • Do you know that particular key which you need? Will that always be constant? – Reshma Oct 5 '16 at 12:30
  • Yes I do know the key I need. Essentially I have an outer loop (looping around a list), each iteration of this loop provides me with a key which I want to use to access records in the map. Hope that makes sense. – Richard Penwell Oct 5 '16 at 12:51
  • I'm not sure I understand your question fully, but are you looking for something like for(value val : acctErpMap.get(key).values()){ //do logic } What type of Map is it? Is it a Map<Id,List<SObject>>? – Todd Sprinkel Oct 5 '16 at 13:36
  • I've posted an answer which might help, but without an edit to your question, which includes the type of the map, as @ToddSprinkel mentions, we won't be able to help you much further. – battery.cord Oct 5 '16 at 13:39
  • Yes the map I think does need to be Map<Id,List<SObject>> - as I've now included in code snippet. In which case I guess I would then have unique values as keys to the map. So then I probably need the for loop mentioned by you @ToddSprinkel to access the data. I guess the other part of the puzzle was populating a map with a list. – Richard Penwell Oct 5 '16 at 14:34
3

You can only have one value per key in a map. Calling Map.put(...) on the same key will replace the existing value in the given key.

Try running the snippet below in a developer console to display this behavior.

Map<String, Boolean> mapAndValues = new Map<String, Boolean>();

// Assign multiple values to same key 
mapAndValues.put('test', true);
mapAndValues.put('test', false);

System.debug(mapAndValues.get('test')); // will return false

An alternative option to using put on the same key would be to use a list type as the value to the map.

Map<String, List<Boolean>> mapAndValues = new Map<String, List<Boolean>>();

// Assign empty list  
mapAndValues.put('test', new List<Boolean>());

// Modify list reference from get 
mapAndValues.get('test').add(true);
mapAndValues.get('test').add(false);

System.debug(mapAndValues.get('test')); // will return (true, false) 

To iterate over the records in your list as specified in your question, you'll need to create a loop which acts on the list provided from calling get on the key.

// First log id to be used to get other records 
System.debug(logginglevel.INFO, 'PersonAccount DEBUG: MAP key = ' + id);  

// Loop over list at specified key 
for (ERP_Customer__c erp:acctErpMap.get(id))  
{  
    // Log each record 
    System.debug(logginglevel.INFO, 'PersonAccount DEBUG: MAP value = ' + erp.Id);         
}

To check if a key is in a map, you need to use the method containsKey(...), as opposed to the method contains.

someMap.containsKey(someKey); // returns either true or false 
  • 1
    Whilst I was helped by comments (rather than an answer) asking me for further information given by @ToddSprinkel, this answer was also useful in my working out what to do. As this is the only actual answer I will mark it up as solving the issue, but in fact both did - thanks... – Richard Penwell Oct 5 '16 at 15:39
  • Guess I'll have to open another one for the syntax error - a bit new to this, but cannot work it out!! – Richard Penwell Oct 5 '16 at 15:52
  • If you're having trouble getting adjusted, I'd recommend taking a day or two to try the Apex Developer Trailhead. It might help. – battery.cord Oct 5 '16 at 16:02
  • Figured it out and posted my final code now - I don't disagree with your suggestion regarding Trailhead though! Thanks. – Richard Penwell Oct 7 '16 at 11:44
  • Lifesaver. Great common sense answer to how to make a list from the map. – amanda fouts Jun 28 '17 at 16: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.