Can I remove element from a list being looped through

  • 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.

  • 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);
        }
    } 
    

    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.

  • 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;
    
  • 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++;
        }
    }
    

    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 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.

    Hmmm. When I did this, I had diff results. I'll check my work again. Sorry

    No problem @cropredy :) Appreciate your suggestions and corrections on posts.

  • 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);
        }
    } 
    
  • 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();
    }
    
    }
    

    Apex is not Java, although they share behaviors extensively. If this solution also applies to Apex, please [edit] to clarify that.

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM

Tags used