How to convert the nested hierarchical object to flatten objects by using LINQ? I know that we can easily use foreach loop to achieve that. But I'm wondering if there is a way to write it in LINQ.
class Person{
public int ID {get;set}
public string Name {get;set}
public List<Person> Children {get;}
}
Data :
ID : 1
Name : Jack
Children
2 | Rose
3 | Paul
I like to convert this data into flatten format like below.
1 | Jack
2 | Rose
3 | Paul
How can we do it with Linq?
If you want it to flatten an arbitrarily deep tree of people, I suggest the following:
public IEnumerable<Person> GetFamily(Person parent)
{
yield return parent;
foreach (Person child in parent.Children) // check null if you must
foreach (Person relative in GetFamily(child))
yield return relative;
}
There isn't really any good way to shorten this with LINQ, because anonymous lambdas can't call themselves recursively without implementing Y. You could "reduce" the above method to
return parent.Children.SelectMany(p => GetFamily(p))
.Concat(new Person[] { parent });
or alternatively
yield return parent;
foreach (Person relative in parent.Children.SelectMany(GetFamily))
yield return relative;
but that seems sort of unnecessary to me.
This is a nice, generic and reusable extension method:
static public IEnumerable<T> Descendants<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> descendBy)
{
if (!source.IsNullOrEmpty())
{
foreach (T value in source)
{
yield return value;
if (!descendBy(value).IsNullOrEmpty())
{
foreach (T child in descendBy(value).Descendants<T>(descendBy))
{
yield return child;
}
}
}
}
}
In the case above, use like this:
var allChildren = parent.Children.Descendants(p => p.Children);
One minor nit is that it doesn't include the original parent in the list, you'll need to do that.
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