最佳实践c#中链表的递归展平

时间:2015-01-24 10:49:02

标签: c# linq linked-list

我构建了一个主类TaskHolder的数据结构, 包含List<Task>Task包含另一个List<Task>Name。 是否有一个LINQ单行代码,可以将所有嵌套的名称检索为扁平的字符串数组?

这是基本结构:

Public class TaskHolder
  List<Task>

Public class Task
  String Name
  List<Task>

2 个答案:

答案 0 :(得分:2)

看起来你无法在没有递归的情况下实现它。它可以是这样的:

    static IEnumerable<string> Flatten(Task task)
    {
        return new[] {task.Name}.Concat(task.Tasks.SelectMany(Flatten));
    }

    //.. and then
    var allNames = Flatten(taskHolder.Task);

答案 1 :(得分:0)

您也可以编写自己的LINQ扩展方法来执行此类操作,并使用类似堆栈的内容来避免显式递归(如果嵌套非常深,则更好):

  public static class LinqExtensions
  {
    public static IEnumerable<TP> FlattenProperties<T, TP>(this IEnumerable<T> outers,
        Func<T, TP> propertySelector, Func<T, IEnumerable<T>> innersSelector)
    {
      Stack<T> stack = new Stack<T>(outers);
      while (stack.Any())
      {
        T outer = stack.Pop();

        TP prop = propertySelector(outer);
        yield return prop;
        if (innersSelector(outer) != null)
        {
          foreach (var inner in innersSelector(outer))
            stack.Push(inner);
        }
      }
    }
  }

然后您可以编写如下内容:

TaskHolder th = new TaskHolder() { ... };
var names = th.Tasks.FlattenProperties(x => x.Name, x => x.Tasks).ToList();