+ Start a Discussion
Vijay@sfdcVijay@sfdc 

avoid below loop inside loop using map

Hello everyone,

Can any one explain me,  how to avoid below loop inside loop using map , can any one explain if i would write bellow code, will it get Hit by governer limits. Thanks Advance. 
 
for(String acct : acc)
    {
        List<String> contlist = new List<String>();
        for(Contact c : trigger.new)
        {
            if(acct == c.AccountId)
            contlist.add(c.id);   
        }
       
    }

Thanks 
 
Best Answer chosen by Vijay@sfdc
Amit Chaudhary 8Amit Chaudhary 8
Please check below sample code
Set<Id> setAccId = new Set<ID>();
List<Contact> lstCont = [select accountID,FirstName,lastName from contact limit 10];

For(Contact cont: lstCont)
{
	setAccId.add(cont.accountID); // Get All AccountId
}

Map<Id,Account> mapAcc = new Map<Id,Account>( [ select id,name from Account where id in :setAccId ] ); 

For(Contact cont: lstCont)
{
	if( mapAcc.containsKey(cont.accountID) ) 
	{
		Account acc = mapAcc.get(cont.accountID);
		System.debug('Account------------>'+acc);
	}
}



We can use the Map over list to avoide query inside for loop with above example

If we use List and not Map
trigger ContactTriggerWithList on Contact (before insert) {
    // Here taking the Set because we don't need to maintain duplicate
    Set<Id> accIdSet = new Set<Id>();
    
    for(Contact con: Trigger.new) {
        if(con.AccountId != null) {
            accIdSet.add(con.AccountId);
        }
    }
    
    if(!accIdSet.isEmpty()) {
        List<Account> accList = [Select Id, Name, Type from Account where Id IN: accIdSet];
        
        for(Contact con: Trigger.new) {
            if(con.AccountId != null) {
                for(Account acc: accList) {
                    if(con.AccountId == acc.Id) {
                        con.Acc_Type__c = acc.Type;
                    }
                }
            }
        }
    }
}
Same Trigger using the Map:
 
trigger ContactTriggerWithMap on Contact (before insert) {
    // Here taking the Set because we don't need to maintain duplicate
    Set<Id> accIdSet = new Set<Id>();
    
    for(Contact con: Trigger.new) {
        if(con.AccountId != null) {
            accIdSet.add(con.AccountId);
        }
    }
    
    if(!accIdSet.isEmpty()) {
        Map<Id, Account> accMap = new Map<Id, Account>([Select Id, Name, Type from Account where Id IN: accIdSet]);
        
        for(Contact con: Trigger.new) {
            if(con.AccountId != null) {
                con.Acc_Type__c = accMap.get(con.AccountId).Type;
            }
        }
    }
}





Please let us know if this will help you
 

All Answers

ManojSankaranManojSankaran
Dear Vijay,

Below is the way you can avoid the for loop.

Map<id,Account> AccountMap = new Map<id,Account>([select id,name from account LIMIT 50000]);

List<String> contlist = new List<String>();
for(Contact c : trigger.new) {
if(AccountMap.containsKey(c.accountId))
      contlist.add(c.id);
}


Mark it as answer if it solves your query.



Thanks
Manoj S

 
Amit Chaudhary 8Amit Chaudhary 8
Please check below sample code
Set<Id> setAccId = new Set<ID>();
List<Contact> lstCont = [select accountID,FirstName,lastName from contact limit 10];

For(Contact cont: lstCont)
{
	setAccId.add(cont.accountID); // Get All AccountId
}

Map<Id,Account> mapAcc = new Map<Id,Account>( [ select id,name from Account where id in :setAccId ] ); 

For(Contact cont: lstCont)
{
	if( mapAcc.containsKey(cont.accountID) ) 
	{
		Account acc = mapAcc.get(cont.accountID);
		System.debug('Account------------>'+acc);
	}
}



We can use the Map over list to avoide query inside for loop with above example

If we use List and not Map
trigger ContactTriggerWithList on Contact (before insert) {
    // Here taking the Set because we don't need to maintain duplicate
    Set<Id> accIdSet = new Set<Id>();
    
    for(Contact con: Trigger.new) {
        if(con.AccountId != null) {
            accIdSet.add(con.AccountId);
        }
    }
    
    if(!accIdSet.isEmpty()) {
        List<Account> accList = [Select Id, Name, Type from Account where Id IN: accIdSet];
        
        for(Contact con: Trigger.new) {
            if(con.AccountId != null) {
                for(Account acc: accList) {
                    if(con.AccountId == acc.Id) {
                        con.Acc_Type__c = acc.Type;
                    }
                }
            }
        }
    }
}
Same Trigger using the Map:
 
trigger ContactTriggerWithMap on Contact (before insert) {
    // Here taking the Set because we don't need to maintain duplicate
    Set<Id> accIdSet = new Set<Id>();
    
    for(Contact con: Trigger.new) {
        if(con.AccountId != null) {
            accIdSet.add(con.AccountId);
        }
    }
    
    if(!accIdSet.isEmpty()) {
        Map<Id, Account> accMap = new Map<Id, Account>([Select Id, Name, Type from Account where Id IN: accIdSet]);
        
        for(Contact con: Trigger.new) {
            if(con.AccountId != null) {
                con.Acc_Type__c = accMap.get(con.AccountId).Type;
            }
        }
    }
}





Please let us know if this will help you
 
This was selected as the best answer
Vijay@sfdcVijay@sfdc
Thanks for quick reply  Amit and ManojSankaran :)

I got so much clearity with  your example code regarding looping. Amit, thanks for your great examples, 
But i still have one doubt. if we would have written below code. does it hit governer limits.  if answer is yes . could you please tel us
how can we handle that situation
for(Contact con: Trigger.new) {
            if(con.AccountId != null) {
                for(Account acc: accList) {
                    if(con.AccountId == acc.Id) {
                        con.Acc_Type__c = acc.Type;
                    }
                }
            }
        }

Thanks
 
Amit Chaudhary 8Amit Chaudhary 8
Please update your code like below
Set<Id> setAccId = new Set<Id>();
for(Contact con: Trigger.new) 
{
	if(con.AccountId != null) 
	{
		setAccId.add(con.AccountId);
	}	
}

if( setAccId.size() > 0 )
{

	Map<Id,Account> mapAccount = new Map<Id,Account>( [ select id,Type from Account where id in:setAccId ] );

	for(Contact con: Trigger.new) 
	{
		if( con.AccountId != null && mapAccount.containsKey(con.AccountId) ) 
		{
			Account acc = mapAccount.get(con.AccountId);
			con.Acc_Type__c = acc.Type;
		}
	}
	
}
Let us know if this will help you
 
Vijay@sfdcVijay@sfdc
Thanks Amit,its really helped me :)