【问题标题】:Getting last item in tree hierarchy获取树层次结构中的最后一项
【发布时间】:2014-11-05 04:30:24
【问题描述】:

我有一个支持多层次层次结构的菜单。我创建了一个函数来获取树中的最后一项并返回其 ID。我需要这个 ID,这样我就可以隐藏管理页面上的下移箭头。

虽然这可行,但我花了 2 天时间试图找到一种 LINQ 方法来做同样的事情。所以我的问题是:

-是否有可能以纯粹的 LINQ 方式做到这一点? -如果有,怎么做?

我的 MenuItem 模型如下所示:

public partial class MenuItem
{
    public MenuItem()
    {
        this.ChildMenuItems = new HashSet<MenuItem>();
    }

    public int Id { get; set; }
    public int MenuItemTypeId { get; set; }
    public int MenuId { get; set; }
    public string DisplayText { get; set; }
    public string Controller { get; set; }
    public string Action { get; set; }
    public Nullable<int> ParentMenuItemId { get; set; }
    public int Rank { get; set; }

    public virtual MenuItemType MenuItemType { get; set; }
    public virtual Menu Menu { get; set; }
    public virtual ICollection<MenuItem> ChildMenuItems { get; set; }
    public virtual MenuItem ParentMenuItem { get; set; }
}

我的递归函数如下所示:

public static int GetLastMenuItemId(List<MenuItem> menuItems)
{
    foreach (MenuItem menuItem in menuItems.OrderBy(mi => mi.Rank))
    {                
        lastId = menuItem.Id;
        if (menuItem.ChildMenuItems.Any())
        {
            GetLastMenuItemId(menuItem.ChildMenuItems.ToList());
        }
    }
    return lastId;
}

此外,我的菜单树目前如下所示:

Categories: 8 Parent: n/a
Admin: 1 Parent: n/a
    Manage Menus: 2 Parent: 1
        Manage Menus: 7 Parent: 2
        ------------: 5 Parent: 2
        Menus: 3 Parent: 2
        Menu Item Types: 4 Parent: 2
        Menu Items: 6 Parent: 2
    Manage Categories: 9 Parent: 1
    Manage Clicks: 10 Parent: 1
    Manage Comments: 11 Parent: 1
    Manage Images: 12 Parent: 1
    Manage Ratings: 13 Parent: 1

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    我将向您的 MenuItem 类添加一个函数,用于检查当前 MenuItem 在父 MenuItem 的子 MenuItems 集合中的位置。

    public List<MenuItem> FlattenedChildNodes {
      get {
        var ret = new List<MenuItem>();
    
        foreach (var item in ChildMenuItems) {
           ret.Add(item);
    
           if(item.ChildMenuItems != null) {
              ret.AddRange(item.FlattenedChildNodes);
           }
        }
    
        return ret;
      }
    }  
    
    
    
    public bool IsLastChild {
          get {
            if (ParentMenuItem == null) // return false if we have no parent (it's the root node)
               return false;
            else // return true iff we're the last child in the parent's collection of children
               return (ParentMenuItem.FlattenedChildNodes.ToList().IndexOf(this) == (ParentMenuItem.FlattenedChildNodes.ToList().Count - 1));
          }
        }
    

    【讨论】:

    • 这是否支持多层深度,其中一个级别的最后一项不一定是树中的最后一项?为了清楚起见,我添加了当前的菜单树结构。
    • 我想是的。我假设如果 MenuItem 是任何级别的最后一个孩子,您不希望出现向下箭头?在您的示例中,管理员:1 父:n/a,菜单项:6 父:2,和管理评级:13 父:1 将没有向下箭头。
    • 您还必须添加一个根节点,以便每个显示的节点都有一个父节点(否则无法判断 Admin: 1 Parent: n/a 是否是级别 1 中的最后一个 MenuItem MenuItems 的集合。
    • 不幸的是,我只希望最底部的项目,在上面的示例中,ID 13,隐藏向下箭头。我已经编写了菜单项在树上上下移动的代码,我只需要隐藏它不能降低的箭头。至于根节点,我使用不同的类作为菜单的根节点(称为“Menu”),而不是另一个 MenuItem 节点。这是出于其他原因(管理多个菜单),我不想改变它。
    • 我会考虑您的建议,但我仍然有兴趣找到一个 LINQ 语句/查询来执行与我的函数相同的操作。
    猜你喜欢
    • 2023-03-24
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多