简体   繁体   中英

Removing an item from a list of items

My Code:

    protected void Page_Load(object sender, EventArgs e)
    {
        ABC ABCDetails;

        if(condition)
        {
            //ABCClient is a soap service that returns ABCDetails which consists of an array[] ABCDetails.ABCLineItemsAuto which is a list but for some reason it would show up as an array when returned from the service I check that it is declared a list in the service end.  
            ABCDetails = new ABCClient().GetABC(param1,param2).FirstOrDefault();

            foreach (var item in ABCDetails.ABCLineItemsAuto)
            {
                if (filterItemsDB.Any(c => c.itemCODE == item.itemType))
                {
                    //if its in the filterItemsDB which ia a list from databse table do something
                }
                else
                {
                    //if its not remove the item from the ABCDetails.ClaimLineItemsAuto which is an ARRAY[]

                    ABCDetails.ABCLineItemsAuto.ToList().Remove(item);
                }
            }
        }


    }

My Goal:

  • to remove the item from the list if it does not belong to the table from DB

My Issue:

  • the Remove(item) runs fine and does not throw any error but does not remove the item from ABCDetails.ABCLineItemsAuto array.

My effort:

  • tried to research and find any different methods for removing an item from list or array none of them have this issue

Not sure whats wrong here?

I am unable to use ABCDetails.ABCLineItemsAuto.Remove(item) as the .Remove() is not available for array[] ABCDetails.ABCLineItemsAuto .

ABCClient is a soap service that returns ABCDetails which consists of an array[] ABCDetails.ABCLineItemsAuto which is a list but for some reason it would show up as an array when returned from the service I check that it is declared a list in the service end.

You have the logic slightly backwards. When you call .ToList() , you're creating a copy of the original list. Then when you call .Remove() , you're removing the item from that copy.

What you can do instead is call .ToList() on the item in the foreach condition (to avoid getting an error about modifying the enumeration), and then remove the item from the actual list inside the body:

Update: Since the type you're dealing with is an Array , an easy way around this is to convert it to a List first, since it has the handy Remove() method. Then at the end, you can take the list and assign it back to the array if you need to. I updated the code to show how that might look:

var lineItemsList = ABCDetails.ABCLineItemsAuto.ToList();

// Use a copy of the list in your foreach condition
foreach (var item in lineItemsList.ToList())
{
    if (filterItemsDB.Any(c => c.itemCODE == item.itemType))
    {
        // Do something here, details aren't relevant to this question
    }
    else
    {
        lineItemsList.Remove(item);
    }
}

ABCDetails.ABCLineItemsAuto = lineItemsList.ToArray();
ABCDetails.ABCLineItemsAuto.ToList().Remove(item);

The ToList actually creates a new List and removes the itme from that list. It does not alter the original list in ABCDetails.ABCLineItemsAuto .

You could rewrite the whole foreach block with 1 statement like this using RemoveAll :

var lst = ABCDetails.ABCLineItemsAuto.ToList();
lst.RemoveAll(item => filterItemsDB.All(c => c.itemCODE != item.itemType));
ABCDetails.ABCLineItemsAuto = lst.ToArray();

This is a round about way of doing it as you just indicated that ABCDetails.ABCLineItemsAuto is an array.

The statement:

ABCDetails.ABCLineItemsAuto.ToList()

will give you a new collection ie List<T> and when you are calling Remove() it is removing element form that new List<T> not from ABCLineItemsAuto .

What you need to do is hold that same collection as reference of List<T> and then call Remove() on it.

When we call ToList() we get a new List<T> back.

When you call ToList() a new List is instantiated. The item is being removed from this new one, but it's kept on the source. Remove it just calling ABCDetails.ABCLineItemsAuto.Remove(item) .

You can achieve this without the loop too:

if(condition)
{
    //ABCClient is a soap service that returns ABCDetails
    ABCDetails = new ABCClient().GetABC(param1,param2).FirstOrDefault();

    ABCDetails.ABCLineItemsAuto = ABCDetails.ABCLineItemsAuto.Except(ABCDetails.ABCLineItemsAuto.Where(i => filterItemsDB.Any(f => f.itemCODE == i.itemType)));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM