【问题标题】:Recursively Create a Menu using two Lists使用两个列表递归创建菜单
【发布时间】:2017-12-08 02:30:47
【问题描述】:

我在使用 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 个条目,这样不会太贪心吗?

【问题讨论】:

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


    【解决方案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;}
    }
    

    然后,您可以使用 List&lt;CategoryModel&gt; 作为菜单的视图模型,而不是使用 CatDocViewModel

    【讨论】:

    • 哦,是的,这真是个好主意,我将其标记为已接受。所以假设我必须首先找到每个文档/类别的孩子?我也在想我也许可以使用链表来使用递归(这样我不使用 for 循环,这可能会导致一些执行错误)。
    • 我不确定这样做的效率如何。这实际上取决于您的集合的大小。虽然有一些方法可以将列表转换为树结构。这是一个例子:stackoverflow.com/questions/947831/…
    • 运行它需要 1.8 秒,但有时只需 350 毫秒,我猜它与一些编译的东西有关? (我现在正在查找这个)。我想,我最多可以比较 30*30 个结果。所以那将是 900 次操作,我认为这可以吗?谢谢你的链接,我去看看
    猜你喜欢
    • 2020-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多