Reputation: 191
I have a nested list that contains
public class Person
{
public Person(string name)
{
this.Name = name;
}
public string Name { get; set; }
public List<Person> Childs { get; set; }
}
The list can be used like:
var Persons = new List<Person>();
Persons.Add(new Person("Eric"));
Persons[0].Childs = new List<Person>();
Persons[0].Childs.Add(new Person("Tom"));
Persons[0].Childs.Add(new Person("John"));
Persons[0].Childs[0].Childs = new List<Person>();
Persons[0].Childs[0].Childs.Add(new Person("Bill"));
Persons.Add(new Person("John");
How can I iterate over the list Persons
and remove all items with the name "John"? If the name is John the node with the name John and all underlaying subitems should be removed.
Upvotes: 2
Views: 1050
Reputation: 2857
Here is a recursive method that removes all persons with the specified name. You can call it like RemoveAllWithName(Persons, "John");
.
private void RemoveAllWithName(List<Person> people, string name)
{
for(int i = people.Count - 1; i >= 0; --i) {
Person person = people[i];
if(person.Name == name) {
people.RemoveAt(i);
} else if(person.Childs != null) {
RemoveAllWithName(person.Childs, name);
}
}
}
Upvotes: 0
Reputation: 117029
You're better off not removing the elements from the existing structure but instead to return a new structure without the "John"'s.
Here's how:
List<Person> Except(List<Person> people, string name) =>
people
.Where(p => p.Name != name)
.Select(p => new Person(p.Name)
{
Childs = Except(p.Childs ?? new List<Person>(), name) // Case typo in method name
})
.ToList();
If you start with your original data:
var Persons = new List<Person>()
{
new Person("Eric")
{
Childs = new List<Person>()
{
new Person("Tom"),
new Person("John")
{
Childs = new List<Person>()
{
new Person("Bill")
}
}
}
},
new Person("John")
};
You can now run this:
List<Person> PersonsNotJohn = Except(Persons, "John");
That gives:
Upvotes: 2
Reputation: 87
static void Main(string[] args)
{
var Persons = new List<Person>();
Persons.Add(new Person("Eric"));
Persons[0].Childs = new List<Person>();
Persons[0].Childs.Add(new Person("Tom"));
Persons[0].Childs.Add(new Person("John"));
Persons[0].Childs[0].Childs = new List<Person>();
Persons[0].Childs[0].Childs.Add(new Person("Bill"));
Persons.Add(new Person("John"));
RemoveAllWithName("John", Persons);
Persons.ForEach(x=>Print(x));
}
private static void RemoveAllWithName(string name, List<Person> persons)
{
if (persons != null && persons.Any())
{
persons.RemoveAll(x => x.Name == name);
}
if (persons != null && persons.Any())
{
persons.ForEach(x => RemoveAllWithName(name, x.Childs));
}
}
private static void Print(Person person)
{
if (person != null)
{
Console.WriteLine(person.Name);
person.Childs?.ForEach(Print);
}
}
Upvotes: 0
Reputation: 1509
Here you go.
Add Namespace
using System.Linq;
Use the below one liner
Persons.RemoveAll(x => x.Name == "John");
Upvotes: 0