2010-07-18 63 views
2

我有一个递归对象,链表真:如何将递归对象转换为C#中的集合?

public class LinkedList 
{ 
    public string UniqueKey { get; set; } 
    public LinkedList LinkedList { get; set; } 
} 

的LinkedList会有一些对象图将在LinkedList.LinkedList最终结束== NULL。

我想将图中的所有对象放到LinkedList集合中,以便我可以遍历它们。我如何在C#中执行此操作?我觉得好像有一个非常简单的方法来使用yield或Linq voodoo来做这件事情?

回答

2

像这样的东西应该工作。如果你能控制课程,你可以直接使用IEnumerable

public class LinkedListEnumerable : IEnumerable<string> 
{ 
    LinkedList list; 
    public LinkedListEnumerable(LinkedList l) 
    { 
     this.list = l; 
    } 

    public IEnumerator<string> GetEnumerator() 
    { 
     LinkedList l = list; 
     while(l != null) 
     { 
      yield return l.UniqueKey; 
      l = l.Next; 
     } 
    } 
} 

然后,您可以使用for-each循环遍历LinkedListEnumerable

+0

啊,这是正确的。除非逐字回答问题,否则它应该是'yield return l'而不是'yield return l.UniqueKey'吧?所有这一切对于OP来说应该很容易就能把那部分弄清楚。 – 2010-07-18 03:06:34

0

这是你想要的吗?

public class LinkedList 
{ 
    public string UniqueKey { get; set; } 
    public LinkedList LinkedList { get; set; } 

    public IEnumerable<LinkedList> GetAllNodes() 
    { 
     if (LinkedList != null) 
     { 
      yield return LinkedList; 
      foreach (var node in LinkedList.GetAllNodes()) 
       yield return node; 
     } 
    } 
} 
+2

这不是非常有效。对于包含100个项目的列表,您将创建100个枚举器,最后一个项目在返回给调用者之前必须先通过所有项目。 – Guffa 2010-07-18 02:04:37

0

有没有很好的LINQ方法标准.NET库,允许一些优雅的LINQ巫术,但你可以从MoreLINQ项目中使用Generate方法和这样写:

Enumerable 
    .Generate(list, l => l.LinkedList) 
    .TakeWhile(l => l != null).Select(l => l.UniqueKey); 

它使用Generate到创建所有元素的“无限”列表 - 它实际上并不是无限的,因为它是懒惰生成的,并且只要我们在最后找到null值(使用TakeWhile)就会停止使用它。然后我们使用Select来返回一个值序列(而不是链表节点)。

这实质上是一种很好的陈述方式,用于表达Matthew发布的while循环解决方案(它应该具有大致相似的性能)。

编辑Generate方法是这样的:

IEnumerable<T> Generate(T current, Func<T, T> generator) { 
    while(true) { 
    yield return current; 
    current = generator(current); 
    } 
} 
+0

这真棒,但不幸的是我不能添加任何其他库到项目中。我将在未来的产品上使用它! – 2010-07-18 03:02:41

+0

@Geoffrey:您可以将'Generate'方法添加到您的项目中(这只是3行代码)。 – 2010-07-18 03:12:38

相关问题