Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing items from a list when a condition is met

I'm writing a multi-threaded download manager where download info is managed by a class I wrote (called DownloadOperation). Downloads are held in a list (called download). I need to remove the objects from the list when a function in the class (queryCompleted) returns true but found out that elements could not be removed from lists from within a foreach loop. What is the best way to have the same effect? I'm relatively new to C# so pardon my stupidity.

private void removeInactiveDownloads()
    {
        foreach (DownloadOperation dl in download)
        {
            if (dl.queryComplete() == true)
            {
                // if download is no longer in progress it is removed from the list.
                download.Remove(dl);
            }
        }
    }
like image 279
user2544563 Avatar asked Jul 02 '13 23:07

user2544563


People also ask

How do you remove an element from a list based on condition?

To remove elements from ArrayList based on a condition or predicate or filter, use removeIf() method. You can call removeIf() method on the ArrayList, with the predicate (filter) passed as argument. All the elements that satisfy the filter (predicate) will be removed from the ArrayList.

How do you remove an element from a while iterating through a list?

If you want to delete elements from a list while iterating, use a while-loop so you can alter the current index and end index after each deletion.

What are the two methods for removing items from a list?

The methods are remove(), pop() and clear(). It helps to remove the very first given element matching from the list. The pop() method removes an element from the list based on the index given. The clear() method will remove all the elements present in the list.


2 Answers

List<T> has a method

public int RemoveAll(
    Predicate<T> match
)

that removes all elements matching a predicate: http://msdn.microsoft.com/en-us/library/wdka673a.aspx

Therefore I suggest something like:

download.RemoveAll(x => x.queryComplete());

(note that == true is not needed since .queryComplete() already returns true or false!)

like image 161
Patashu Avatar answered Sep 30 '22 13:09

Patashu


Iterate backwards in a For loop instead of a Foreach loop

for(int i = download.Count; i >= 0; i--)
{
    if (download[i].queryComplete())
    {
       // if download is no longer in progress it is removed from the list.
       download.RemoveAt(i);
    }
}
like image 42
keyboardP Avatar answered Sep 30 '22 12:09

keyboardP