Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Суммирование элементов древовидного списка 
V
    Опции темы
no0b
Дата 9.10.2013, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 9.10.2013

Репутация: нет
Всего: нет



Использую компонент 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 - ид родителя
Собственно вопрос вот в чем: как для всех родительских элементов рассчитать сумму дочерних?
PM MAIL   Вверх
likegift
Дата 10.10.2013, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 208
Регистрация: 14.10.2008

Репутация: нет
Всего: 3



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

Это сообщение отредактировал(а) likegift - 10.10.2013, 09:50
PM MAIL   Вверх
mihryak
Дата 10.10.2013, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 19
Всего: 36



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));
        }

PM MAIL ICQ   Вверх
likegift
Дата 11.10.2013, 06:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 208
Регистрация: 14.10.2008

Репутация: нет
Всего: 3



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

А ему не нужна информация о родителях, он сумму детей считает, а не родителей. Да и подходы для хранения детей\родителей одинаковы не только по сложности, но и по занимаемой памяти. Не говоря уже о том, что метод, реализующий сумму детей в "моем" случае, будет на порядок проще и понятнее, чем ваш.
PM MAIL   Вверх
mihryak
Дата 11.10.2013, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 19
Всего: 36



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

ну как же одинаковы?
1. сложность
- для удаления ребёнка нужно будет отыскать его в коллекции - код поиска + время на поиск
- нужно предусмотреть контроль за данными, например, чтобы один ребёнок не присутствовал дважды (обе проблемы решаются с помощью HashSet)
- поиск родителя (хоть именно эта задача не требует этого, не факт, что не потребуется никогда) существенно сложнее
- храние в базе данных без предварительной трансформации невозможно
2. память
- само заворачивание в объект-коллекцию требует дополнительной памяти
- если количество детей стого не определено раз и навсегда, то неизбежен перерасход памяти при добавлении элементов (если массив - то явное создание нового, если List или HashSet - неявное увеличение в большим запасом при превышении ожидаемого размера)
PM MAIL ICQ   Вверх
no0b
Дата 23.10.2013, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 9.10.2013

Репутация: нет
Всего: нет



Цитата(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 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0911 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.