将层次排序方法转换为 C# 中的扩展

Convert hierarchical sort method to an extension in C#

我有一种方法可以将父子列表排序为层次结构。效果很好,但可以将其转换为通用扩展方法吗?

List<Task> tasks = new List<Task>( );

tasks.Add( new Task { Id = 1, ParentId = null, Title = "" } );
tasks.Add( new Task { Id = 2, ParentId = 4, Title = "" } );
tasks.Add( new Task { Id = 3, ParentId = 2, Title = "" } );
tasks.Add( new Task { Id = 4, ParentId = null, Title = "" } );
tasks.Add( new Task { Id = 5, ParentId = 2, Title = "" } );
tasks.Add( new Task { Id = 6, ParentId = null, Title = "" } );
tasks.Add( new Task { Id = 7, ParentId = 6, Title = "" } );

方法:

var lookup = tasks.ToLookup( x => x.ParentId );

IEnumerable<Task> heirarchySort( int? pid ) => lookup[pid]
    .SelectMany(
        x => new[] { x }.Concat( heirarchySort( x.Id ) )
    );

IEnumerable<Task> sortedTasks = heirarchySort( null );

提前致谢。

以下解决方案使用两个表达式来访问项目的 Id 和 ParentId;如果 depth-first 如您的代码所示,则返回的订单:

static class Extension
{
    public static IEnumerable<T> DFS<T>(this IEnumerable<T> list, Func<T, int> getId, Func<T, int?> getParentId)
    {
        var lookup = list.ToLookup(x => getParentId(x));
        IEnumerable<T> hierarchySort(int? pid) => lookup[pid].SelectMany(x => new[] { x }.Concat(hierarchySort(getId(x))));
        return hierarchySort(null);
    }
}

用法:

IEnumerable<Task> sortedTasks = tasks.DFS(t => t.Id, t => t.ParentId);

它仍然hard-codes Id 的类型为 int;如果需要,可以将其作为附加模板参数。