Writing a line to delete a list for a list

I am trying to make an effective delete method to work on a list. This situation is as follows:

Say for example. I have a (potentially) massive list of names:

Alex Smith Anna Hobb Bertie Blackman Bill Clinton David Smith David Warner George Jung George Washington William Wobbits 

Suppose this is a List<Person> with a Person having the FirstName and LastName properties. As in the example, there is an opportunity for two people having the same FirstName. What I need to do is look through the list and delete all the davids, for example.

I went through all the davids, adding DeletePerson to the list, then repeating the loop for each DeletePerson and deleting. I'm sure there will be a more efficient method? Efficiency is not important in this application, but it seems like a very long way to do it, and I assume that after the letter D in the first name, we know that we will no longer add DeletePerson to the list (assuming the list is sorted alphabetically)

Thanks!

+4
source share
2 answers

For a concise approach, use RemoveAll.

 list.RemoveAll(person => person.FirstName == "David") 

for (maybe I have not run any tests) an efficient approach based on the order in the list, use List.RemoveRange - but you will need to find the indexes.

 class NameComparer : IComparer<Name> { public int Compare(Name x, Name y) { return x.First.CompareTo(y.First); } } ... ... var comparer = new NameComparer(); var david = new Name { First = "David" }; int guess = list.BinarySearch(david, comparer); int start, end; start = list.FindLastIndex(guess, person => person.First != "David") + 1; if (start > 0 && list[start].First == "David") { end = list.FindIndex(guess, person => person.First != "David"); list.RemoveRange(start, end - start); } 
+3
source

Updated answer:

If we are not allowed to use the RemoveAll or LINQ functions that do all the work for us, this is the way to do it more "manually":

  List<Person> newPersons = new List<Person>(); foreach (Person person in persons) { if (person.FirstName != "David") newPersons.Add(person); } persons = newPersons(); 

Building a new list is very fast in .NET. Deleting items one by one is slow, because each item to be deleted must first be found in the list, and then when it is deleted, the rest of the list must be moved up to fill the gap. This is much slower than the method described above.

To make the delete operation even faster, the list can be saved in sorted order or grouped by name. But then the initial creation of the list will be slower.


Old answer:

It seems you are interested in a concise solution, not optimal performance. If you are using .NET 3.5, you can use this:

 persons = persons.Where(person => person.FirstName != "David").ToList(); 

Oh, and List has a RemoveAll method:

 names.RemoveAll(person => person.FirstName == "David"); 

(Note Jimmy posted the RemoveAll idea before I did it.)

+6
source

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


All Articles