First we need to describe how to make the first aggregation of the depth of the tree:
//seed: leafNode -> accumulate //func: interiorNode, children accumulates -> accumulate public static TAccumulate Aggregate<TAccumulate>( this TreeNode root, Func<TreeNode, TAccumulate> seed, Func<TreeNode, List<TAccumulate>, TAccumulate> func) { if (root.Children == null || !root.Children.Any()) return seed(root); return func(root, children.Select(child => child.Aggregate(seed, func)).ToList()); }
Then we can use this to make a modification, such as requested by you:
tree.Aggregate( leaf => new { Keep = leaf.NodeType == TreeNode.NodeType.Category, Node = leaf }, (node, children) => { var removal = new HashSet<TreeNode>( children.Where(child => !child.Keep).Select(child => child.Node)); node.Children.RemoveAll(removal.Contains); return new { Keep = children.Any(child => child.Keep), Node = node }; });
This provides a concise, declarative way to describe which transformation you want to apply to your tree without going into details of the workaround in the description of the transformation.
source share