Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Суммирование элементов древовидного списка


Автор: no0b 9.10.2013, 10:32
Использую компонент treeview, источник данных List<MovWithArticle> элементов 
 
Код

public class MovWithArticle
{
public Guid Id { get; set; }    
public decimal? MSum { get; set; }
public string Name { get; set; }
public Guid Parent { get; set; }
}


Id - ид, Parent - ид родителя
Собственно вопрос вот в чем: как для всех родительских элементов рассчитать сумму дочерних?

Автор: likegift 10.10.2013, 09:49
вы хотите посчитать сумму дочерних элементов в то время, когда о самом их существовании вам ничего не известно. Может, стоит подумать над классом еще чуток и parent заменять на childs?

Автор: mihryak 10.10.2013, 15:47
likegift, тогда не будет информации о родителе
держать и то, и то - не слишком разумно из-за возможной рассинхронизации
более того, подход с хранением коллекции детей сам по себе сложнее, чем хранением лишь информации о родителе

единственный недостаток у структуры топик-стартера - невозможность "по-человечески" задавать узлы верхнего уровня
Guid.Empty - так себе вариант, практически magic value, я бы Guid? посоветовал использовать

Код

        public class Test
        {
            public int Id { get; set; }
            public int? ParentId { get; set; }
            public int Value { get; set; }
        }

        private int GetSum(List<Test> collection, int rootId)
        {
            var root = collection.First(m => m.Id == rootId);

            return root.Value + collection.Where(m => m.ParentId == rootId).Sum(child => GetSum(collection, child.Id));
        }

Автор: likegift 11.10.2013, 06:27
Цитата(mihryak @ 10.10.2013,  18:47)
likegift, тогда не будет информации о родителе
держать и то, и то - не слишком разумно из-за возможной рассинхронизации
более того, подход с хранением коллекции детей сам по себе сложнее, чем хранением лишь информации о родителе

А ему не нужна информация о родителях, он сумму детей считает, а не родителей. Да и подходы для хранения детей\родителей одинаковы не только по сложности, но и по занимаемой памяти. Не говоря уже о том, что метод, реализующий сумму детей в "моем" случае, будет на порядок проще и понятнее, чем ваш.

Автор: mihryak 11.10.2013, 15:32
Цитата(likegift @  11.10.2013,  07:27 Найти цитируемый пост)
подходы для хранения детей\родителей одинаковы не только по сложности, но и по занимаемой памяти

ну как же одинаковы?
1. сложность
- для удаления ребёнка нужно будет отыскать его в коллекции - код поиска + время на поиск
- нужно предусмотреть контроль за данными, например, чтобы один ребёнок не присутствовал дважды (обе проблемы решаются с помощью HashSet)
- поиск родителя (хоть именно эта задача не требует этого, не факт, что не потребуется никогда) существенно сложнее
- храние в базе данных без предварительной трансформации невозможно
2. память
- само заворачивание в объект-коллекцию требует дополнительной памяти
- если количество детей стого не определено раз и навсегда, то неизбежен перерасход памяти при добавлении элементов (если массив - то явное создание нового, если List или HashSet - неявное увеличение в большим запасом при превышении ожидаемого размера)

Автор: no0b 23.10.2013, 13:26
Цитата(mihryak @ 10.10.2013,  15:47)
likegift, тогда не будет информации о родителе
держать и то, и то - не слишком разумно из-за возможной рассинхронизации
более того, подход с хранением коллекции детей сам по себе сложнее, чем хранением лишь информации о родителе

единственный недостаток у структуры топик-стартера - невозможность "по-человечески" задавать узлы верхнего уровня
Guid.Empty - так себе вариант, практически magic value, я бы Guid? посоветовал использовать

Код

        public class Test
        {
            public int Id { get; set; }
            public int? ParentId { get; set; }
            public int Value { get; set; }
        }

        private int GetSum(List<Test> collection, int rootId)
        {
            var root = collection.First(m => m.Id == rootId);

            return root.Value + collection.Where(m => m.ParentId == rootId).Sum(child => GetSum(collection, child.Id));
        }

Благодарю за ответ! Задачу решил на стороне бд, после долгих и бесплодных экспериментов с рекурсией smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)