-1

Suppose I have two list of T, I need to remove from list A all the elements that are not in list B. I did this:

A.RemoveAll(item => !B.Contains(item));

this working pretty well, but if the list B does not contains any elements, this code will remove all the items from the list A and it shouldn't. Why happen that?

Nameless
  • 9
  • 1

4 Answers4

1

Well, it removes everyhing because the condition is true for all items in list A.

Since you want to remove only items from A if list B is not empty:

if(B.Any())
    A.RemoveAll(item => !B.Contains(item));
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Using the `Any()` method on `List`/`ICollection` isn't good idea because it uses enumerators instead of the `Count` property. – Yoh Deadfall Mar 20 '18 at 14:05
  • @YohDeadfall: so what? But `Any` is more menaingful than counting items. Especially with collections the overhead of `Any` is negligible. With other types you have to use it anyway. However, checking it once is always better than [checking it for every item](https://stackoverflow.com/a/49385931/284240). In other words: https://stackoverflow.com/questions/305092/which-method-performs-better-any-vs-count-0#comment4595700_305156 – Tim Schmelter Mar 20 '18 at 14:06
0

This happens because list B doesn't contain any items. And you are saying remove everything from A that doesn't exist in B. Effectively saying remove everything because B doesn't have anything

Mats
  • 109
  • 2
  • 8
0

Well it happens because if B is empty, for all elements in A the expression !B.Contains(item) is true.

Try this:

A.RemoveAll(item => B.Count > 0 && !B.Contains(item));

or better avoid iterating at all if B is empty:

if (B.Count > 0) A.RemoveAll(item => !B.Contains(item));
René Vogt
  • 43,056
  • 14
  • 77
  • 99
  • This works perfectly thanks! I don't understand why you should edit the question with Any instead of Count, maybe the other user can explain it – Nameless Mar 20 '18 at 13:49
-1

It happens because !B.Contains(item) returns true for all elements from A. If you don't want this to happen, just check if B is not empty:

A.RemoveAll(item => B.Any() && !B.Contains(item));
the_joric
  • 11,986
  • 6
  • 36
  • 57