function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
bouscalbouscal 

Remove items from List A if they appear in List B

Trying to be a good coder and using lists instead of loops but now I want to remove items from a List but I don't know the index of said items.

List<Contact>myRecipients = [SELECT id, firstname, lastname, email FROM contact WHERE firstname='Tim'];
List<Task> myTasks=[SELECT id, whoid, subject FROM task WHERE createddate >:dtRange];

I need to determine if the whoid in myTasks exists in myRecipients and if so, myRecipients.remove(x);

Do I need to loop through myRecipients in reverse order and then for each iteration loop through myTasks or is there a better way?

for(Integer c=myRecipients.size()-1; c>=0; --c){
                for(Task t:myTasks){
                    if(myRecipients.get(c).id == t.whoid){
                        myRecipients.remove(c);
                    }
                }
            }
Best Answer chosen by bouscal
Elie.RodrigueElie.Rodrigue
You could first do your task query, create at list of id containing your whoids and filtering in the contact query : 

List<Task> myTasks=[SELECT id, whoid, subject FROM task WHERE createddate >:dtRange];

List<Id> whoIds = new List<Id>();
for(Task t  : myTasks)
{
     whoIds.add(t.WhoId);
}
List<Contact>myRecipients = [SELECT id, firstname, lastname, email FROM contact WHERE firstname='Tim' and Id not in : whoIds];

You can also have a look at the set object that you could use instead of list. There's a contains and a remove mtehod if you have the specific object ( in your example you dont have the object)
Or you could get it to work using a map.