Reputation: 9578
Considering the following class:
public class MenuItemModel
{
public MenuItemModel()
{
this.items = new List<MenuItemModel>();
}
[DataMember]
public int id { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public string type { get; set; }
[DataMember]
public string route { get; set; }
[DataMember]
public ProcessIndex ProcesIndex { get; set; }
[DataMember]
public bool isCapable { get; set; }
[DataMember]
public List<MenuItemModel> items { get; set; }
}
I have a list of these MenuItemModel instances. Some of those instance have subitems (in the items property).
I want to grab all the menuitems, including the subitems with a LINQ to objects query that matches a given processindex, how can this be done ?
Upvotes: 0
Views: 68
Reputation: 236248
You can use following extension method to flatten menu items hierarchy
public static IEnumerable<T> Flatten<T>(
this IEnumerable<T> source, Func<T, IEnumerable<T>> childrenSelector)
{
foreach(var item in source)
{
yield return item;
foreach(var child in childrenSelector(item).Flatten(childrenSelector))
yield return child;
}
}
Or non-recursive one:
public static IEnumerable<T> Flatten<T>(
this IEnumerable<T> source, Func<T, IEnumerable<T>> childrenSelector)
{
Stack<T> items = new Stack<T>(source);
while (items.Any())
{
T item = items.Pop();
yield return item;
foreach (var child in childrenSelector(item))
items.Push(child);
}
}
Usage:
var allItems = items.Flatten(i => i.items);
You can use simple Enumerable.Where
filter to get only items with required process index.
Upvotes: 1