List <List <int> Method Remove ()

I would like to use the Remove () method in a list of lists, but it does not work for me.
A simple example should say it all:

 List<List<int>> list = new List<List<int>>(); list.Add(new List<int> { 0, 1, 2 }); list.Add(new List<int> { 1, 2 }); list.Add(new List<int> { 4 }); list.Add(new List<int> { 0, 1, }); list.Remove(new List<int> { 1, 2 }); 

If I use RemoveAt (1), it works fine, but Remove () does not.
This is obviously the same reason that this code returns false:

 List<int> l1 = new List<int>(); List<int> l2 = new List<int>(); l1.Add(1); l2.Add(1); bool b1 = l1 == l2; // returns False bool b2 = l1.Equals(l2); // returns False too 

It seems to me that I cannot just compare two lists or even arrays. I can use loops instead of Remove (), but there should be an easier way.

Thanks in advance.

+4
source share
6 answers

First approach:

 List<int> listToRemove = new List<int> { 1, 2 }; list.RemoveAll(innerList => innerList.Except(listToRemove).Count() == 0); 

It also removes the list {2, 1}

Second approach (preferred):

 List<int> listToRemove = new List<int> { 1, 2 }; list.RemoveAll(innerList => innerList.SequenceEqual(listToRemove)); 

This deletes all lists that contain the same sequence as the list provided.

+6
source

The problem is that List<T> does not override Equals and GetHashCode , which List<T> will use when trying to find an element. (In fact, it will use the default IEquatable<T> , which means that it will use the IEquatable<T> implementation if the object implements it, and if necessary returns to object.Equals / GetHashCode ). Equals will return false because you are trying to delete another object, and the default implementation is just to compare the links.

Basically, you should write a method for comparing two lists for equality and use this to find the index of the record you want to delete. Then you delete by index (using RemoveAt ). EDIT: As noted, Enumerable.SequenceEqual can be used to compare lists. This is not as effective as it could be, because it was not initially checked whether the scores are equal when they can be easily calculated. Also, if you only need to compare the List<int> values, you can avoid calling the virtual method to match the equality.

Another alternative is to refuse to use List<List<int>> in the first place - use List<SomeCustomType> , where SomeCustomType includes List<int> . Then you can implement IEquatable<T> in this type. Note that this may also allow you to encapsulate the corresponding logic in a user type as well. I often find that by type you have “nested” collection types, a custom type encapsulates the value of the internal collection more efficiently.

+11
source

Eliminating a list is a reference equality. It will not delete the list if it does not have the same link as the list in the external list. You can create a new type that implements equality as established equality, rather than referential equality (or do you also take care of order?). Then you can make lists of this type.

+4
source

It just won’t work, because you get attached to delete the new list (the new keyword dictates this), and not one of the ones you just entered. For example, the following code creates two different lists, since they are not the same list, however they look the same:

 var list0 = new List<int> { 1, 2 }; var list1 = new List<int> { 1, 2 }; 

However, the following creates one single list, but two links to the same list:

 var list0 = new List<int> { 1, 2 }; var list1 = list0; 

Therefore, you must keep a link to the lists that you put there if you want to act with them in the future in order to:

 var list0 = new List<int> { 1, 2 }; listOfLists.Remove(list0); 
+2
source

These are different objects. Try the following:

  List<int> MyList = new List<int> { 1, 2 }; List<List<int>> list = new List<List<int>>(); list.Add(new List<int> { 0, 1, 2 }); list.Add(MyList); list.Add(new List<int> { 4 }); list.Add(new List<int> { 0, 1, }); list.Remove(MyList); 
+1
source

You need to provide a link to the list you want to delete:

 list.Remove(list[1]); 

which really coincides with

 list.RemoveAt(1); 
0
source

Source: https://habr.com/ru/post/1347382/


All Articles