【问题标题】:Recursively remove items from Tree从树中递归删除项目
【发布时间】:2011-10-13 05:00:31
【问题描述】:

我有一个结构如下的树形视图:

var myTree = myRepository.GetTree();

对象文件夹的结构如下:

public class Folder
{
   public string Name { get; set; }
   public List<Folder> Folders { get; set; }
   public Folder Parent { get; set; }
}

假设一个存储库返回给我类似这样的结构:

MyFolder
   -MyChild01
   -MyChild02
      -MySubChild01       
   -MyChild03
      -MySubChild02

我需要递归读取树中的所有项目,如果项目的名称包含“02”,我必须从树中删除该项目。所以最终的结果应该是:

MyFolder
   -MyChild01
   -MyChild03

我想看看如何使用带有匿名委托或递归函数的递归 LINQ。

【问题讨论】:

    标签: linq recursion


    【解决方案1】:

    您可以采取多种方法来做到这一点。

    最简单的做法是采用函数式方法并递归重建树,排除与您的模式匹配的文件夹。

    static Folder Filtered(Folder root, Func<Folder, bool> predicate)
    {
        return new Folder
        {
            Name = root.Name,
            Parent = root.Parent,
            Folders = root.Folders
                .Where(predicate)
                .Select(subFolder => Filtered(subFolder, predicate))
                .ToList(),
        };
    }
    
    Folder myTree = ...;
    var filtered = Filtered(myTree, f => f.Name.Contains("02"));
    

    如果出于某种原因您不想创建文件夹的新实例,而是想修改现有实例,则必须进行一些调整,但仍然同样简单。

    static Folder Filtered(Folder root, Func<Folder, bool> predicate)
    {
        // make use of the RemoveAll() method for lists
        root.Folders.RemoveAll(subFolder => !predicate(subFolder));
        foreach (var subFolder in root.Folders)
        {
            Filtered(subFolder, predicate);
        }
        return root;
    }
    

    【讨论】:

    • 我将选择这个,因为我无法进行更改并创建新实例,但我必须过滤现有实例,这篇文章对此进行了详细说明。
    • 太棒了——正是我想要的(第二个例子)谢谢!
    【解决方案2】:
        static void Main(string[] args)
        {
            var root = new Folder()
            {
                Name = "MyFolder",
                Folders = new List<Folder>(){
                        new Folder() {Name="MyChild01", Folders = new List<Folder>()},
                        new Folder() {Name="MyChild02", Folders = new List<Folder>(){
                            new Folder() { Name="MySubChild01", Folders = new List<Folder>()}}
                        },
                        new Folder() {Name="MyChild03", Folders = new List<Folder>(){
                            new Folder() { Name="MySubChild02", Folders = new List<Folder>()}}
                        },
                    }
            };
    
            var filtered = applyFilter(root, f=>!f.Name.EndsWith("02"));
    
        }
    
        static Folder applyFilter( Folder root, Predicate<Folder> filter )
        {
            var result = new Folder() { Name = root.Name, Parent = root.Parent };
            result.Folders = (from child in root.Folders
                             where filter(child)
                             select applyFilter(child, filter)).ToList();
            return result;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-19
      • 2012-03-04
      • 2023-04-03
      • 2015-04-08
      • 1970-01-01
      • 2020-09-06
      • 1970-01-01
      相关资源
      最近更新 更多