9

In apex, how can I remove an element from a list being looped?

List<String> companyinfos=new List<String>();
companyinfos.add('a1');
companyinfos.add('a2');
companyinfos.add('a3');
companyinfos.add('b1');
companyinfos.add('b2');

integer index=0;
For(String s: companyinfos)
{
    if(s.contains('a')){
        companyinfos.remove(index);
        index--;
    }
index++;
}  


System.debug(companyinfos);  

ERROR: Cannot modify a collection while it is being iterated.

18

As long as you don't use the shorthand iteration technique for(Object a : Objects) and use a traditional for loop, it works fine (you must traverse the list in reverse order - thanks Willem)

Try this:

for (Integer i = (companyinfos.size()-1) ; i>= 0 ; i--){
    String s = companyInfos[i];
    if(s.contains('a')){
        companyinfos.remove(i);
    }
} 
1
  • 6
    Note that looping in reverse order is essential because otherwise, if you remove an item and the list gets shoter, you'll get an index out of bound exception if you try to fetch item past the end of the list. – Willem Mulder May 22 '17 at 9:43
6

Salesforce prohitbits (or at least used to do that earlier) removing items from list while traversing it.

So, the solution would be to create another list, store all desired elements in there. For e.g.

List<CompanyInfo> companyinfos=new List<companyinfos>();
List<CompanyInfo> finalList=new List<companyinfos>();
companyinfos.add(***);
....

integer index=0;
For(CompanyInfo info: companyinfos)
{

    if(info.item!=****)
    {
        finalList.add(info);
    }
}  
companyinfos = finalList;
0
1

Using While loop to remove an element from a list while being looped

If you want to remove an element in a list by checking for a specific condition, you can use while loop instead of for loop. By doing so, you could remove element from list using index.

Here is the sample code to do so

Integer i = 0;
while (i < companyinfos.size()){
    if(companyinfos.get(i).contains('a')){
        companyinfos.remove(i);
    } else {
        i++;
    }
}
4
  • this does not work as the act of removing shifts the remaining elements to one lower array index value. For example, if all companies contain a, you'll retain the second, fourth, sixth, ... entries. – cropredy Jun 10 '19 at 20:08
  • @cropredy This does work and its a tested code. Because even though the array index shifts, the index only increments when it doesn't find a match and if a match is found, it won't increment the index, hence it covers that scenario. – Vijay Ganji Jun 11 '19 at 5:36
  • Hmmm. When I did this, I had diff results. I'll check my work again. Sorry – cropredy Jun 11 '19 at 13:01
  • No problem @cropredy :) Appreciate your suggestions and corrections on posts. – Vijay Ganji Jun 11 '19 at 13:26
0

First You should find the index of that letter from companyinfos list the remove that index Try this and let me Know

for (Integer i = (companyinfos.size()-1) ; i>= 0 ; i--)
{
    if(companyinfos.contains('a')){
    Integer index =companyinfos.indexOf('a');
    companyinfos.remove(index);
    }
} 
-1

In Java it's agood practice to use the iterator when removing something from a list being looped:

List<String> companyinfos=new List<String>();
companyinfos.add('a1');
companyinfos.add('a2');
companyinfos.add('a3');
companyinfos.add('b1');
companyinfos.add('b2');

Iterator<String> it = companyinfos.iterator();

while(it.hasNext()){

String next = it.next();

if(next.contains('a')){
  it.remove();
}

}
1
  • 1
    Apex is not Java, although they share behaviors extensively. If this solution also applies to Apex, please edit to clarify that. – David Reed May 28 '20 at 15:00

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.