如何通过LINQ将树夷为平地?

如何通过LINQ将树夷为平地?

所以我有一棵简单的树:

class MyNode{
 public MyNode Parent;
 public IEnumerable<MyNode> Elements;
 int group = 1;}

我有一个IEnumerable<MyNode>..我想要一份清单MyNode(包括内部节点对象(Elements)作为一个单一清单Where group == 1..如何通过LINQ做这样的事情?


摇曳的蔷薇
浏览 418回答 3
3回答

缥缈止盈

你可以像这样把一棵树夷为平地:IEnumerable<MyNode>&nbsp;Flatten(IEnumerable<MyNode>&nbsp;e)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;e.SelectMany(c&nbsp;=>&nbsp;Flatten(c.Elements)).Concat(new[]&nbsp;{e});}然后你可以过滤group使用Where(...).若要获得“风格积分”,请转换Flatten到静态类中的扩展函数。public&nbsp;static&nbsp;IEnumerable<MyNode>&nbsp;Flatten(this&nbsp;IEnumerable<MyNode>&nbsp;e)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;e.SelectMany(c&nbsp;=>&nbsp;c.Elements.Flatten()).Concat(e);}为了获得“更好的风格”的一些分数,转换Flatten获取树和生成后代的函数的泛型扩展方法:public&nbsp;static&nbsp;IEnumerable<T>&nbsp;Flatten<T>( &nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;IEnumerable<T>&nbsp;e, &nbsp;&nbsp;&nbsp;&nbsp;Func<T,IEnumerable<T>>&nbsp;f)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;e.SelectMany(c&nbsp;=>&nbsp;f(c).Flatten(f)).Concat(e);}这样调用此函数:IEnumerable<MyNode>&nbsp;tree&nbsp;=&nbsp;....var&nbsp;res&nbsp;=&nbsp;tree.Flatten(node&nbsp;=>&nbsp;node.Elements);如果您希望按预先顺序而不是按顺序排列,请在Concat(...).

手掌心

为了完整起见,下面是dasbrakenlight和EricLippert的答案的组合。单元测试和一切。*-)&nbsp;public&nbsp;static&nbsp;IEnumerable<T>&nbsp;Flatten<T>( &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;IEnumerable<T>&nbsp;items, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func<T,&nbsp;IEnumerable<T>>&nbsp;getChildren) &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;stack&nbsp;=&nbsp;new&nbsp;Stack<T>(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach(var&nbsp;item&nbsp;in&nbsp;items) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stack.Push(item); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while(stack.Count&nbsp;>&nbsp;0) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;current&nbsp;=&nbsp;stack.Pop(); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield&nbsp;return&nbsp;current; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;children&nbsp;=&nbsp;getChildren(current); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(children&nbsp;==&nbsp;null)&nbsp;continue; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp;(var&nbsp;child&nbsp;in&nbsp;children)&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stack.Push(child); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;}
打开App,查看更多内容
随时随地看视频慕课网APP