Building Ordering a tree as a list in C#

前端 未结 3 1361
旧巷少年郎
旧巷少年郎 2021-01-14 18:05

I have a list of C# entities. My entity is defined as follows:

public class Item
{
    // the id of an item
    public Guid ID { get; set; }

    // if this          


        
3条回答
  •  醉酒成梦
    2021-01-14 18:12

    Even though you said that you wanted the items sorted by level (ascending) and then createDate (ascending), your diagram says otherwise. It looks like you actually want the items sorted in a way that would allow you to print out a tree, such that each item is after its parent and before its children and its parents "younger siblings". This is a topological sort which is substantially different from what you asked for, but not that hard:

    class ItemComparer : IComparer
    {
        // allow us to look up parent Items by GUID
        IDictionary itemLookup;
    
        public ItemComparer(IEnumerable list)
        {
            itemLookup = list.ToDictionary(item => item.ID);
            foreach (var item in list)
                SetLevel(item);
        }
    
        int SetLevel(Item item)
        {
            if (item.Level == 0 && item.ParentID.HasValue)
                item.Level = 1 + itemLookup[item.ParentID.Value].Level;
            return item.Level;
        }
    
        public int Compare(Item x, Item y)
        {
            // see if x is a child of y
            while (x.Level > y.Level)
            {
                if (x.ParentID == y.ID)
                    return 1;
                x = itemLookup[x.ParentID.Value];
            }
            // see if y is a child of x
            while (y.Level > x.Level)
            {
                if (y.ParentID == x.ID)
                    return -1;
                y = itemLookup[y.ParentID.Value];
            }
            // x and y are not parent-child, so find common ancestor
            while (x.ParentID != y.ParentID)
            {
                x = itemLookup[x.ParentID.Value];
                y = itemLookup[y.ParentID.Value];
            }
            // compare createDate of children of common ancestor
            return x.CreateDate.CompareTo(y.CreateDate);
        }
    }
    

    Invoke it like this:

    // if List
    items.Sort(new ItemComparer(items));
    // if IEnumerable
    var sorted = random.OrderBy(x => x, new ItemComparer(random));
    

提交回复
热议问题