简体   繁体   中英

c# sorting data from an adjacency tree

I have a bunch of data that will be represented as a tree. The control that I'm using requires the data to be ordered correctly.

This is the structure of each node:

public class TreeNode
{
    public Guid id { get; set; }
    public string name { get; set; }
    public int level { get; set; }
    public Guid? parent { get; set; }
    public bool isLeaf { get; set; }    
}

I need a way to sort the data so that I have a list of TreeNodes with the root first, followed by its children and so on. In other words all direct children need to follow the parent in the list.

I would also like subnodes and leaf nodes to be sorted by name. ( > = expandable, o = leaf)

root >
  level1a >         
  level1b >
     level2d >
     level2a o
  level1a o
  level1b o

Is there an easy way to do this?

I'm assuming I'll need some recursive function and not wont be able to sort it using a combination of order by statements (something like list.OrderBy(x => x.parent).ThenBy(x => x.level).ThenBy(x => x.isLeaf); )

You're correct that doing this with a single LINQ expression is not straightforward. This recursive approach should do the trick:

IEnumerable<TreeNode> TreeOrder(
    IEnumerable<TreeNode> nodes)
{
    //Find the root node
    var root = nodes.Single(node => node.parent == null);

    //Build an inverse lookup from parent id to children ids
    var childrenLookup = nodes
        .Where(node => node.parent != null)
        .ToLookup(node => node.parent.Value);

    return TreeOrder(root, childrenLookup);
}

IEnumerable<TreeNode> TreeOrder(
    TreeNode root,
    ILookup<Guid, TreeNode> childrenLookup)
{
    yield return root;

    if (!childrenLookup.Contains(root.id))
        yield break;

    foreach (var child in childrenLookup[root.id])
        foreach (var node in TreeOrder(child, childrenLookup))
            yield return node;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM