Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将列表转换为树_C#_Linq_List_Tree - Fatal编程技术网

C# 将列表转换为树

C# 将列表转换为树,c#,linq,list,tree,C#,Linq,List,Tree,是否可以将列表转换为树,以便在删除父节点时自动删除所有子节点 原因是我有递归的类别,我想显示除子类别(递归)之外的所有类别,我脑海中最简单的方法就是做一些类似于图片中的事情 正如您在本场景中看到的,当我删除红色节点时,所有绿色节点将自动删除它们自己。我有什么选择 这是我正在使用的模型,如果它有什么不同的话 public class Category { public int Id { get; set; } public int? RootCategoryId { get;

是否可以将列表转换为树,以便在删除父节点时自动删除所有子节点

原因是我有递归的类别,我想显示除子类别(递归)之外的所有类别,我脑海中最简单的方法就是做一些类似于图片中的事情

正如您在本场景中看到的,当我删除红色节点时,所有绿色节点将自动删除它们自己。我有什么选择

这是我正在使用的模型,如果它有什么不同的话

public class Category
{
    public int Id { get; set; }

    public int? RootCategoryId { get; set; }
    public virtual Category RootCategory { get; set; }
    public virtual ICollection<Category> ChildCategories { get; set; }
}
例如,当我想编辑一个类别时,我会调用
\u db.Categories.Where(x=>x.Id!=currentlyEditedId)。这将消除当前类别(在图片中,它将删除红色类别),而绿色类别将保留

如何确保如果删除红色的,绿色的也会删除?


最后,我希望有一个包含图片中所有黑色项目的列表。

要删除一个项目,您需要分别删除其中的每个项目;db上下文就是这样工作的。不过,您可以简单地删除所有项目。下面是遍历树的简单算法:

public static IEnumerable<Category> Traverse(Category root)
{
    var stack = new Stack<Category>();

    stack.Push(root);

    while (stack.Any())
    {
        var next = stack.Pop();
        yield return next;
        foreach (var child in next.ChildCategories)
            stack.Push(child);
    }
}
如果您只是想从内存集合中删除某个项,则只需在其父项上调用
remove
。如果没有父节点,只有要删除的节点和根节点,则需要另一种方法来遍历树:

public static bool Remove(Category root, int id)
{
    var stack = new Stack<Category>();

    stack.Push(root);

    while (stack.Any())
    {
        var next = stack.Pop();
        foreach (var child in next.ChildCategories)
        {
            if (child.Id == id)
            {
                next.ChildCategories.Remove(child);
                return true;
            }
            stack.Push(child);
        }
    }

    return false;
}
publicstaticbool-Remove(类别根,int-id)
{
var stack=新堆栈();
栈.推(根);
while(stack.Any())
{
var next=stack.Pop();
foreach(next.ChildCategories中的var child)
{
if(child.Id==Id)
{
next.ChildCategories.Remove(child);
返回true;
}
栈.推(子);
}
}
返回false;
}

这就是我想要的。传入类别列表并删除当前类别列表,然后递归删除其所有子类别列表

/// <summary>
/// Get list of all categories except current one as well as all it's child categories
/// </summary>
/// <param name="id">Current category id</param>
/// <param name="categories">List of categories</param>
/// <returns>List of categories</returns>
public static List<Category> CategoriesWithoutChildren(int id, List<Category> categories)
{
    var currentCategory = categories.Single(x => x.Id == id);
    categories.Remove(currentCategory);

    if (currentCategory.ChildCategories.Count > 0)
    {
        currentCategory.ChildCategories.ToList().ForEach(x =>
        {
            categories = CategoriesWithoutChildren(x.Id, categories);
        });
    }

    return categories;
}
//
///获取除当前类别及其所有子类别之外的所有类别的列表
/// 
///当前类别id
///类别清单
///类别清单
没有子级的公共静态列表类别(int-id,列表类别)
{
var currentCategory=categories.Single(x=>x.Id==Id);
类别。删除(当前类别);
如果(currentCategory.ChildCategories.Count>0)
{
currentCategory.ChildCategories.ToList().ForEach(x=>
{
categories=没有子项的类别(x.Id,categories);
});
}
退货类别;
}

使用刚才显示的
类别
类有什么问题?@Servy问题是他得到了类别的递归树,这太多数据了,他想控制递归的深度。@skmasq他从来没有说过。没有迹象表明数据的数量,或者深度太大而无法管理。@Servy我更新了我的问题,也许现在更清楚了?为什么不能创建一个DeleteChildren(c类)函数
public static bool Remove(Category root, int id)
{
    var stack = new Stack<Category>();

    stack.Push(root);

    while (stack.Any())
    {
        var next = stack.Pop();
        foreach (var child in next.ChildCategories)
        {
            if (child.Id == id)
            {
                next.ChildCategories.Remove(child);
                return true;
            }
            stack.Push(child);
        }
    }

    return false;
}
/// <summary>
/// Get list of all categories except current one as well as all it's child categories
/// </summary>
/// <param name="id">Current category id</param>
/// <param name="categories">List of categories</param>
/// <returns>List of categories</returns>
public static List<Category> CategoriesWithoutChildren(int id, List<Category> categories)
{
    var currentCategory = categories.Single(x => x.Id == id);
    categories.Remove(currentCategory);

    if (currentCategory.ChildCategories.Count > 0)
    {
        currentCategory.ChildCategories.ToList().ForEach(x =>
        {
            categories = CategoriesWithoutChildren(x.Id, categories);
        });
    }

    return categories;
}