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