用一个语句压平一棵树(列表的列表)?
感谢 nHibernate,我使用的一些数据结构是列表中的列表中的列表。例如,我有一个名为“category”的数据对象,它有一个 .Children 属性,可解析为类别列表......每个类别都可以有子项......等等。
我需要找到一种方法,从该结构中的顶级类别开始,并获取整个结构中所有子级的列表或数组或类似的内容 - 因此所有子级的所有子级等等,都扁平化为一个列表。
我确信它可以通过递归来完成,但我发现递归代码很难完成,并且我相信在 .Net 4 中一定有一种使用 Linq 或类似方法的更直接的方法 - 有什么建议吗?
Thanks to nHibernate, some of the data structures I work with are lists within lists within lists. So for example I have a data object called "category" which has a .Children property that resolves to a list of categories ... each one of which can have children ... and so on and so on.
I need to find a way of starting at a top-level category in this structure and getting a list or array or something similar of all the children in the entire structure - so all the children of all the children etc etc, flattened into a single list.
I'm sure it can be done with recursion, but I find recursive code a pain to work through, and I'm convinced there must be a more straightforward way in .Net 4 using Linq or somesuch - any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是完成这项工作的扩展方法:
您可以像这样使用它:
上面的解决方案进行深度优先遍历,如果您想要广度优先遍历,您可以这样做:
它还有一个好处是非-递归...
更新:实际上,我只是想到了一种使深度优先遍历非递归的方法...这里是:
我使用
LinkedList
因为插入是O(1) 次操作,而插入List
则为 O(n)。Here's an extension method that does the job:
You can use it like this:
The solution above does a depth-first traversal, if you want a breadth-first traversal you can do something like this:
It also has the benefit of being non-recursive...
UPDATE: Actually, I just thought of a way to make the depth-first traversal non-recursive... here it is:
I'm using a
LinkedList<T>
because insertions are O(1) operations, whereas insertions to aList<T>
are O(n).假设您的 Category 类看起来像这样:
我认为没有一种“简单”的非递归方法可以做到这一点;如果您只是寻找单个方法调用来处理它,“简单”的方法是将递归版本写入单个方法调用中。可能有一种迭代方法可以做到这一点,但我猜它实际上相当复杂。这就像在不使用微积分的情况下寻找曲线切线的“简单”方法。
无论如何,这可能会做到这一点:
Assuming your Category class looks something like:
I don't think there's an "easy" non-recursive way to do it; if you're simply looking for a single method call to handle it, the "easy" way is to write the recursive version into a single method call. There's probably an iterative way to do this, but I'm guessing it's actually pretty complicated. It's like asking the "easy" way to find a tangent to a curve without using calculus.
Anyway, this would probably do it:
鉴于 @EZHart 提到的类,您还可以使用辅助方法来扩展它,我认为在这种情况下更简单。
Given the class @E.Z.Hart mentions, you could also extend it with a helper method for this which I think is simpler in this case.
如果广度优先遍历没问题,并且您只想使用一些短的非递归内联代码(实际上是 3 行),请创建一个使用根元素初始化的列表,然后仅通过一个简单的 for 循环来扩展它:
If breadth-first traversal is OK and you only want to use some short non-recursive inline code (3 lines actually), create a list initialized with your root element(s) and then extend it by just one simple for-loop: