I'm already familiar with Linq but have little understanding of extension methods I'm hoping someone can help me out.
So I have this hierarchical collection pseudo code ie:
class Product
prop name
prop type
prop id
prop List<Product> children
And I have a list of products List products.
Is there any way I can look for product in this collection by the id with a extension method ? In other words I need one item somewhere within the hierarchy.
Here is a generic solution that will short-circuit traversal of the hierarchy once a match is found.
public static class MyExtensions
{
public static T FirstOrDefaultFromMany<T>(
this IEnumerable<T> source, Func<T, IEnumerable<T>> childrenSelector,
Predicate<T> condition)
{
// return default if no items
if(source == null || !source.Any()) return default(T);
// return result if found and stop traversing hierarchy
var attempt = source.FirstOrDefault(t => condition(t));
if(!Equals(attempt,default(T))) return attempt;
// recursively call this function on lower levels of the
// hierarchy until a match is found or the hierarchy is exhausted
return source.SelectMany(childrenSelector)
.FirstOrDefaultFromMany(childrenSelector, condition);
}
}
To use it in your case:
var matchingProduct = products.FirstOrDefaultFromMany(p => p.children, p => p.Id == 27);
You can flatten your tree structure using this extension method:
static IEnumerable<Product> Flatten(this IEnumerable<Product> source)
{
return source.Concat(source.SelectMany(p => p.Children.Flatten()));
}
Usage:
var product42 = products.Flatten().Single(p => p.Id == 42);
Note that this is probably not very fast. If you repeatedly need to find a product by id, create a dictionary:
var dict = products.Flatten().ToDictionary(p => p.Id);
var product42 = dict[42];
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