0

I have two lists with having the same field in a different object. How to compare the list of name is present in my list if yes then its should be update else it should only create a new record not adding the older record in my list.

 List<Project__c > ProjectList= [select id,Name,Opportunity__c from Project__c where Opportunity__c=:oppId];
 List<Role__c> RoleList= [select id,Name,Opportunity__c from Role__c where Opportunity__c=:oppId];

For Example

ProjectList =({Id=001, Name=Marry,Opportunity__c =aoQXX},{Id=002, Name=John,Opportunity__c =aoQXX},{Id=003, Name=Chris,Opportunity__c =aoQXX});

RoleList =(({Id=001, Name=Marry,Opportunity__c =aoQXX},{Id=002, Name=John,Opportunity__c =aoQXX})

Now My Question is I need to add only Chris in my RoleList instead of adding again Marry, john. how would I do that in apex?

for(integer i = 0; i < ProjectList.size(); i++) 
             {
                 for(Role__c Upd :RoleList )
                    {
                      
                        if(ProjectList [i].Name.contains(Upd.Name))
                        {
                            System.debug('Updated needs to done ');
                           
                            
                        }
                       else if(!ProjectList [i].Name.contains(Upd.Name))
                        {
                             System.debug('Insert only third not everything');  
                        }
                    }
             }

if I check my debug statement

Updated needs to done 
Updated needs to done 
Insert only third not everything
Insert only third not everything
Insert only third not everything

but expected should be

**Updated needs to done 
Updated needs to done 
Insert only third not everything**
1
  • Thanks in Advance Jun 15, 2021 at 19:21

1 Answer 1

1

The exact reason may differ but, in general, if you see yourself writing code like this

for(SObject1 obj1 :obj1List){
    for(SObject2 obj2 :obj2List){
        if(obj1.field__c == obj2.field__c){
            // do work
        }
    }
}

that's a red flag.

Nested loops are unavoidable at times (and not inherently evil), but if you're doing a comparison like if(obj1.field__c == obj2.field__c) (which is nearly functionally identical to your ProjectList [i].Name.contains(Upd.Name)), that ends up being incredibly wasteful. There is a better way.

The general idea is that you have two separate loops, and use a Set or a Map.
The first loop gathers data, and the second loop compares against that data.

Applied to your situation, that'd look something like this

Set<String> namesWithRoles = new Set<String>();

// gather data loop
for(Role__c role :roleList){
    namesWithRoles.add(role.Name);
}

// comparison loop
for(Project__c project :projectsList){
    if(namesWithRoles.contains(project.Name)){
        // already exists, just do an update
    // There's no need to make this an 'if-else'
    // The only way to get into this else block is if namesWithRoles does not contain
    //   the project's name
    }else{
        // doesn't exist as a role, add it for insert
    }
}

Note that Sets are case-sensitive. Your current code would allow role with name 'Jessica' to count as existing for a project with name 'Jess' (you're using the contains() method from the String class in your provided code), and using a Set, Map, or List would not display that same behavior.

If you need to do a check against multiple fields, then you'd want to start thinking about using a Set<SObject> instead of a Set<String>. Doing that, in effect, is comparing the hashcode of the objects against one another. It ends up being a shorter and faster way to do things compared to comparing multiple fields.

You must log in to answer this question.

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