smuldr
smuldr

Reputation: 324

Is there a better way to remove elements from list using c#?

I have a list of objects. If any of the properties equal null I want that entire element removed from the list. Is there a better way to do it then what I have below.

I've tried for loops and for each and either can't figure out how to do it or don't fully understand how to accomplish my task.

var i = 0;

while (i < filterCriterias.Count())
{
    if (filterCriterias[i].ColumnName == null 
        || filterCriterias[i].Comparator == null 
        || filterCriterias[i].Criteria == null)
    {
        filterCriterias.RemoveAt(i);
    }
    else
    {
        i++;
    }
}

So if I have the list below:

List<Order> orders = new List<Order> 
{
    new Order {ColumnName = null, OperantOrder = null},
    new Order {ColumnName = Session, OperantOrder = ASC},
    new Order {ColumnName = null, OperantOrder = null},
}

I only want the list to only contain the element 1 where columnName = session and operantorder = asc.

Upvotes: 3

Views: 85

Answers (3)

Rufus L
Rufus L

Reputation: 37020

To use a for loop when removing items from a list, it's normally best to start at the last element and work backwards. This way you don't end up skipping items or get an IndexOutOfRange exception because the Count changed during the loop (which happens when removing items in a forward direction):

// Start at the last index and move towards index '0'
for (int i = filterCriterias.Count - 1; i >= 0; i--)
{
    if (filterCriterias[i].ColumnName == null ||
        filterCriterias[i].Comparator == null ||
        filterCriterias[i].Criteria == null)
    {
        filterCriterias.RemoveAt(i);
    }
}

Upvotes: 1

Mureinik
Mureinik

Reputation: 311143

A more idiomatic approach would be to use RemoveAll:

filterCriterias.RemoveAll(c => c.ColumnName == null ||
                               c.Comparator == null ||
                               c.Criteria == null);

Upvotes: 10

Rahul
Rahul

Reputation: 77866

There is no need of removing just select what you want using System.Linq like below. This will return a new collection.

var order = orders.Where(x => x.ColumnName == Session && x.OperantOrder == ASC).ToList(); 

You can as well consider using FirstOrDefault() like

var order = orders.FirstOrDefault(x => x.ColumnName == Session && x.OperantOrder == ASC); 

Upvotes: 1

Related Questions