简体   繁体   中英

How to use conditional in List.ForEach()?

I need to remove items from the HttpSession collection. In the following code, myList contains the same items as Session. If there are items in myList/Session that are not in itemsToRemove, they should be deleted from the session collection.

However, I'm not sure what the lambda syntax should look like. The following isn't correct.

myList.ForEach(x => !itemsToRemove.Contains(x) { Session.Remove(x) });

Any ideas how I can use a lambda expression to put everything on one line to accomplish this task?

Also, is there a way to avoid creating the intermediate list (myList)? I'm only doing that because I can't remove items from Session while iterating through it.

The most naïve way:

myList.Where(x => !itemsToRemove.Contains(x)) // LINQ extension method
      .ToList()                                                                 <----
      .ForEach(x => Session.Remove(x));       // List<T> method so this is required |

Also you can use this:

mystList.Except(itemsToRemove)
        .ToList()
        .ForEach(x => Session.Remove(x));

But to use ForEach the underlying type should be List<T> so you need to call ToList() first. What causes 1 excess enumeration of the whole collection.

I would do this instead:

foreach (var x in mystList.Except(itemsToRemove))
{
    Session.Remove(x)
}

This will minimize the number of enumerations.

First off, abatischev's answer is excellent. It's ideal from both a performance perspective and a readability perspective. If, however, you really want to cram all the functionality into one statement (which I don't recommend), you could try the following:

Session.OfType<string>()
       .Except(itemsToRemove)
       .ToList()
       .ForEach(x => Session.Remove(x));

As abatischev metnioned, the ToList() call costs you an extra enumeration through the collection, which could have a non-trivial performance impact if the collection has a large number of elements in it. However, it means the ForEach() call iterates over a newly created List<string> , which fills the role of your myList and lets you remove items from the Session (since you're iterating through that temporary list, rather than the Session).

(Note that I haven't worked with HttpSessionState objects myself, merely looked at their MSDN article. You may need to replace the string generic type with something else if strings aren't what HttpSessionState holds.)

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