+ Start a Discussion
Surender GiriSurender Giri 

How to avoid for loop inside the for loop

Hi All,

I have written a trigger but i am unable to avoid the for loop inside the for loop. Can anyone please suggest me that how can i resolve this by using map or any other collection.

trigger OfferPartnerTrigger on Offer_Partner__c (After Insert,After Update,After Delete) {
    set<id>OfferId=new set<id>();
    If(Trigger.IsAfter && Trigger.IsInsert || Trigger.IsUpdate){
        for(Offer_Partner__c offr:Trigger.New){
            OfferId.add(offr.Offer__c);
        } 
    }     
    
    If(Trigger.IsAfter && Trigger.IsDelete){
        for(Offer_Partner__c offr:Trigger.old){
            OfferId.add(offr.Offer__c);
        }
    }  
    try{
        MAP<Id,Offers__c> offerMap = new MAP<Id,Offers__c>();
        list<string>partnerIdList=new list<string>();
        list<Offers__c>ofrList=new list<Offers__c>();
        list<Offers__c>offerList=[select id,Partners__c,(select id,name,Consumer__r.PartnerId__c from Offer_Partners__r) from Offers__c where id=:OfferId and id in (select Offer__c from Offer_Partner__c)];
        system.debug('offerList***'+offerList);            
        for(Offers__c ofr:offerList){
            for(Offer_Partner__c oosf:ofr.Offer_Partners__r){
                partnerIdList.add(oosf.Consumer__r.PartnerId__c);
                
                string allstring = string.join(partnerIdList,',');
                ofr.Partners__c=allstring;
                system.debug('oosf.Consumer__r.PartnerId__c***'+oosf.Consumer__r.PartnerId__c);            
                
                ofrList.add(ofr);
            }
            system.debug('partnerIdList***'+partnerIdList);            
        }

        offerMap.putall(ofrList);
        if(offerMap.size()>0){
            update offerMap.values();
        }
    }
    catch(Exception e){
        system.debug('OfferPartnerTrigger' +' '+e+' '+e.getLineNumber());
        
    }
}

Thanks
Best Answer chosen by Surender Giri
Abhishek BansalAbhishek Bansal
Hi Surendra,

You can create a Map where key can be Id of the Offers__c object and value would be String of all the child records.
You can run the query on your child object and then execute a for loop on that list. Now put values in your map by checking the containsKey method. Sample code is given below which you can modify as I am not sure about your use cases:
Map<Id, String> mapOfOfferIdWithPartnerIds = new Map<Id, String>();

for(Offer_Partner__c offPartner : [Select Offer__c, Consumer__r.PartnerId__c from Offer_Partner__c where Offer__c =: Consumer__r.PartnerId__c AND Offer__c in (select Offer__c from Offer_Partner__c)]) {
	if(!mapOfOfferIdWithPartnerIds.containsKey(offPartner.Offer__c)) {
		mapOfOfferIdWithPartnerIds.put(offPartner.Offer__c, '');
	}
	String partnerIdString = mapOfOfferIdWithPartnerIds.get(offPartner.Offer__c);
	partnerIdString = partnerIdString + offPartner.Consumer__r.PartnerId__c + ',';
	mapOfOfferIdWithPartnerIds.put(offPartner.Offer__c, partnerIdString);
}

if(mapOfOfferIdWithPartnerIds.size() > 0) {
	List<Offers__c> offerToUpdate = new List<Offers__c>();
	for(Offers__c offr : [Select Id, Partners__c from Offers__c where Id IN: mapOfOfferIdWithPartnerIds.keySet()]) {
		offr.Partners__c = mapOfOfferIdWithPartnerIds.get(offr.Id);
		offerToUpdate.add(offr);
	}
	if(offerToUpdate.size() > 0) {
		update offerToUpdate;
	}
}

You can replace the above code from line no. 15 to 40. Please take care of syntax errors and API name of the fields. 
 
Note: One more SOQL is used in this approach.

Let me know if  you need more help or information on this.

Thanks,
Abhishek Bansal.