Создание иерархии возражает из плоского списка родителя/ребенка

Один из способов будет использовать NumberFormat .

NumberFormat formatter = new DecimalFormat("#0.00");     
System.out.println(formatter.format(4.0));

Выход:

4.00

20
задан gregmac 14 January 2009 в 20:35
поделиться

3 ответа

Вот функция, которую я закончил тем, что писал. Я использую MPTT, чтобы хранить объекты, таким образом, список в порядке 'левого' значения, которое в основном означает, что родитель всегда прибывает перед любым данным объектом в список. Другими словами, на объект ссылается объект. ParentID всегда уже добавлялся (кроме случая или корневых узлов верхнего уровня).

public class TreeObject
{
    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Name { get; set; }
    public IList<TreeObject> Children { get; set; } = new List<TreeObject>();
}

public IEnumerable<TreeObject> FlatToHierarchy(List<TreeObject> list)
{
    // hashtable lookup that allows us to grab references to containers based on id
    var lookup = new Dictionary<int, TreeObject>();
    // actual nested collection to return
    var nested = new List<TreeObject>();

    foreach (TreeObject item in list)
    {
        if (lookup.ContainsKey(item.ParentId))
        {
            // add to the parent's child list 
            lookup[item.ParentId].Children.Add(item);
        }
        else
        {
            // no parent added yet (or this is the first time)
            nested.Add(item);
        }
        lookup.Add(item.Id, item);
    }

    return nested;
}

и простой тест (который работает в LinqPad):

void Main()
{
    var list = new List<TreeObject>() {
        new TreeObject() { Id = 1, ParentId = 0, Name = "A" },
        new TreeObject() { Id = 2, ParentId = 1, Name = "A.1" },
        new TreeObject() { Id = 3, ParentId = 1, Name = "A.2" },
        new TreeObject() { Id = 4, ParentId = 3, Name = "A.2.i" },
        new TreeObject() { Id = 5, ParentId = 3, Name = "A.2.ii" }
    };

    FlatToHierarchy(list).Dump();
}

Результаты:

enter image description here

, Так как я обновляю это 5 лет спустя, вот рекурсивная версия LINQ:

public IList<TreeObject> FlatToHierarchy(IEnumerable<TreeObject> list, int parentId = 0) {
    return (from i in list 
            where i.ParentId == parentId 
            select new TreeObject {
                Id = i.Id, 
                ParentId = i.ParentId,
                Name = i.Name,
                Children = FlatToHierarchy(list, i.Id)
            }).ToList();
}
28
ответ дан 30 November 2019 в 00:27
поделиться

я предполагаю, что Вы уже знаете родителя всех объектов .

Все, что необходимо сделать, должно выполнить итерации через весь объект списка однажды и добавить текущий объект к дочернему списку его родителя. Только сохраните объекты без родителей во вложенном списке цели.

Вот некоторый псевдо код:

foreach Item item in flatlist
   if item.Parent != null
      Add item to item.Parent.ChildrenList
      Remove item from flatlist
   end if
end for

Что касается получения родителей, от того, что я вижу в Вашем примере, Вы, возможно, должны были бы проанализировать имя и создать стек, когда Вы совершенствуетесь в списке.

Это проблемы взгляды твердый, но это действительно не. Много людей видит эту проблему от неправильного угла; Вы не должны пытаться заполнить каждый, дети перечисляют, а скорее избавляются от дочерних объектов из плоского списка, затем это становится легким.

3
ответ дан 30 November 2019 в 00:27
поделиться

Вот пример, надежда, которой это помогает

class Program
{
    static void Main(string[] args)
    {
        TreeObject a  = new TreeObject() { Name = "Item A" };
        a.Children.Add( new TreeObject() { Name = "Item A.1" });
        a.Children.Add( new TreeObject() { Name = "Item A.2" });

        TreeObject b = new TreeObject() { Name = "Item B" };
        b.Children.Add(new TreeObject() { Name = "Item B.1" });
        b.Children.Add(new TreeObject() { Name = "Item B.2" });

        TreeObject c = new TreeObject() { Name = "Item C" };

        List<TreeObject> nodes = new List<TreeObject>(new[] { a, b, c });

        string list = BuildList(nodes);
        Console.WriteLine(list); // Item A,Item A.1,Item A.2,Item B,Item B.1,Item B.2,Item C

        List<TreeObject> newlist = new List<TreeObject>();
        TreeObject temp = null;

        foreach (string s in list.Split(','))
        {
            if (temp == null || !s.Contains(temp.Name) || temp.Name.Length != s.Length)
            {
                temp = new TreeObject() { Name = s };
                newlist.Add(temp);
            }
            else
            {
                temp.Children.Add(new TreeObject() { Name = s });
            }                              
        }

        Console.WriteLine(BuildList(newlist)); // Item A,Item A.1,Item A.2,Item B,Item B.1,Item B.2,Item C
    }

    static string BuildList(List<TreeObject> nodes)
    {
        StringBuilder output = new StringBuilder();
        BuildList(output, nodes);
        return output.Remove(output.Length - 1, 1).ToString();
    }

    static void BuildList(StringBuilder output, List<TreeObject> nodes)
    {
        foreach (var node in nodes)
        {
            output.AppendFormat("{0},", node.Name);
            BuildList(output, node.Children);
        }
    }
}

public class TreeObject
{
    private List<TreeObject> _children = new List<TreeObject>();

    public string Name { get; set; }
    public Guid Id { get; set; }
    public List<TreeObject> Children { get { return _children; } }
}

}

0
ответ дан 30 November 2019 в 00:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: