I have a question using these same examples - this question is focused on a different issue. Given the following classes:
[XmlRoot]
public class Family {
[XmlElement]
public List<Person> Person;
}
public class Person {
[XmlAttribute("member")]
public MemberType Member { get; set; }
[XmlAttribute("id")]
public int Id { get; set; }
[XmlElement]
public string Surname { get; set; }
[XmlElement]
public string Forename { get; set; }
[XmlElement("Person")]
public List<Person> People;
}
public enum MemberType {
Father,
Mother,
Son,
Daughter
}
If Family
has a method defined as such:
public IEnumerable<Person> Find (Func<Person, bool> predicate) {
// how do I get SelectMany to flatten the list?
foreach (var p in family.Person.SelectMany(p => p)) {
if(predicate(p)) {
yield return p;
}
}
}
I need to be able to execute the predicate over a flattened list of Person
. In the example above SelectMany
is not flattening the list as I had hoped. The above actually won't compile because the inferred type cannot be determined.
How can I get the Family.Person collection to become one flattened list of Person?
Flatten List of Lists Using sum. Summing over inner lists is another solution. The function has two parameters: iterable which is a list of lists and start which is an empty list in our case that serves as the initial flat list to which items of the inner sublists are added.
Flatten the list to "remove the brackets" using a nested list comprehension. This will un-nest each list stored in your list of lists!
To my knowledge, the easiest way to accomplish this is using a helper.
private List<Person> FlattenTree(Person person)
{
var accumulator = new List<Person>();
FlattenPersonHelper(person, accumulator);
return accumulator;
}
private void FlattenPersonHelper(Person person, List<Person> accumulator)
{
accumulator.Add(person);
foreach (var child in person.People)
{
FlattenPersonHelper(child, accumulator);
}
return;
}
You can then run your predicate against this list:
public IEnumerable<Person> Find (Func<Person, bool> predicate) {
var familyRoot = new Person() { People = family.Person };
return FlattenTree(familyRoot).Where(predicate);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With