将LINQ与嵌套(相同类型)合并到对象

时间:2014-05-13 15:30:22

标签: linq

考虑以下课程:

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; }
    }

我有一个这些MenuItemModel实例的列表。其中一些实例有子项(在items属性中)。

我想获取所有的菜单项,包括带有与给定processindex匹配的LINQ to objects查询的子项,如何做到这一点?

1 个答案:

答案 0 :(得分:1)

您可以使用以下扩展方法来展平菜单项层次结构

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;
    }
}

或非递归的:

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);
    }
}

用法:

var allItems = items.Flatten(i => i.items);

您可以使用简单的Enumerable.Where过滤器来仅获取具有所需过程索引的项目。