使用两个列表递归创建菜单

时间:2017-07-04 14:50:16

标签: c# asp.net-mvc recursion razor

我无法使用ASP.NET MVC制作动态菜单,其中菜单是根据Active Directory中的Groups进行组织的。为了减少无用的细节,我检索了两个列表:一个给了我菜单的folders,另一个给了我所有的files。如果知道folders可以subfolderssubsubfolders等等,那么如何递归创建菜单呢?在我的项目中,他们被称为我有两个模型DocumentModelCategoryModel,如下所示:

//Files
public class DocumentModel
{
    public long iDDocument { get; set; }
    public long iDCategory { get; set; }
    public string docName { get; set; }
    public string link { get; set; }
    public string type { get; set; }
}
//Folders
public class CategoryModel
{
    public long iDCategory { get; set; }
    public string nom { get; set; }
    public int iDParentCategory { get; set; }
}

然后我使用更大的模型将它们传递给我的视图:

public class CatDocViewModel
{
    public IEnumerable<CategoryModel> catModel { get; set; }
    public IEnumerable<DocumentModel> docModel { get; set; }
}

所以我的想法是在局部视图中制作递归方法。使用Razor helpers我可以制作一个递归方法,但是我很难用这些方法。

出现的另一个问题是我使用IEnumerable所以我必须循环遍历它们,这对于算法而言代价太高,因为我会递归并再循环等等......?但是由于文件夹的深度未知,我也无法在没有递归的情况下完成它,所以我必须递归,直到我结束然后回滚。但是怎么样?

我认为没有人可以制作算法,但如果你有一些方向指出我,那么我可以深入研究递归并理解如何做到这一点?

编辑正如标记答案中所建议的,以下是我要做的事情然后构建Child列表:

    public List<CategoryModel> getDocumentChilren(List<CategoryModel> categories, List<DocumentModel> documents)
    {
        foreach(var cat in categories)
        {
            if (cat.idParentCategory == 0)
                continue;
            foreach(var nextCat in categories)
            {
                if (nextCat.idParentCategory == cat.idParentCategory && nextCat.idCategory != cat.idCategory)
                    cat.childCategories.Add(nextCat);
            }
            foreach (var nextDoc in documents)
            {
                if (nextDoc.idCategory == cat.idCategory)
                    cat.childDocuments.Add(nextDoc);
            }
        }
        return categories;
    }

这是O(n ^ 2)我相信它还可以吗?如果我要做一个估计,我每个循环有大约20个条目,所以这不会太贪心吗?

1 个答案:

答案 0 :(得分:1)

我会在更适合树形结构的类中组织文件夹,如下所示:

public class CategoryModel
{
    public long iDCategory { get; set; }
    public string nom { get; set; }
    public List<CategoryModel> ChildCategories {get;set;}
    public List<DocumentModel> ChildDocuments {get;set;}
}

然后,您可以使用CatDocViewModel作为菜单的视图模型,而不是使用List<CategoryModel>