Коллеги!
Столкнулся с небольшой проблемой — не могу нигде найти нормлальный алгоритм по группировке данных в массиве. Писать на костылях не совсем айс. Может кто когда-то где-то сталкивался и вдиел хорошее решение.
Смысл такой: есть массив: [Имя , Количество] в котором Имя повторяется, надо сделать другой массив [Имя, Сумма], где Имя — уникальный и отсортированный список из первого массива и Сумма — это сумма Количества из первого массива для повторяющихся элементов имя.
Дело в том, что в основном я работал с БД и на SQL этот запрос выглядет "SELECT Имя, SUM (Количество) FROM Table GROUP BY Имя".
Однако в данной ситуации мне надо проделать ту-же операцию но без БД совсем, а написать такой код, который бы группировал болты, гайки, шайбы шпильки и прочую штуку на VBA для AutoCAD. Не приделывать же СУБД для простого отчета.
Для описанной задачи не надо ничего "группировать" не надо. Так или иначе придется пробежать по всей таблице.
Если "групп" много, нужно сгородить какой-нибудь словарь для быстрого поиска (или просто бинарным поиском ограничиться).
Здравствуйте, ylem, Вы писали:
AA>>Дело в том, что в основном я работал с БД
Y>Для описанной задачи не надо ничего "группировать" не надо. Так или иначе придется пробежать по всей таблице. Y>Если "групп" много, нужно сгородить какой-нибудь словарь для быстрого поиска (или просто бинарным поиском ограничиться).
Т.е.:
1 шаг: создаем второй массив, затем делаем вложенный цикл в котором пробегаем по всему певому массиву и при каждом шаге сравниваем со значениями второго массива и суммируем либо добавляем ко второму массиву записи?
2 шаг: сортируем второй массив?
Может есть какие-нибудь красивые алгоритмы для 1 шага с рекурсией и т.п.?
Может у кого есть какие-нибудь примеры такого рода?
> Смысл такой: есть массив: [Имя , Количество] в котором Имя повторяется, надо сделать другой массив [Имя, Сумма], где Имя — уникальный и отсортированный список из первого массива и Сумма — это сумма Количества из первого массива для повторяющихся элементов имя.
Простейшее решение — сортируем массив по ключевому полю (в данном
случае [Имя], после чего все повторяющиеся имена будут идти по порядку.
Теперь пробегаемся по массиву — на каждом шаге, если значение
ключевого поля такое же как и предыдущее — то накапливаем аккумулятор (в
данном случае просто инкрементируем SUM), если нет — то выдаем
[ПредыдущееИмя, SUM], зануляем аккумулятор, обновляем его текущим
значением и идем дальше.
AA>1 шаг: создаем второй массив, затем делаем вложенный цикл в котором пробегаем по всему певому массиву
Куда он вложенный?
Создаем таблицу, в которой будут колонки Имя и Сумма
"Пробегаем" по большому "массиву", для каждого элемента находим в свежесоданном соотв. строку и плюсуем к ней. Если строку не нашли, добавляем с соблюдением порядка необходимой сортировки.
Вопрос, как находим -- бинарного поиска скорее всего хватит на все случаи жизни.
Здравствуйте, ettcat, Вы писали:
>> Смысл такой: есть массив: [Имя , Количество] в котором Имя повторяется, надо сделать другой массив [Имя, Сумма], где Имя — уникальный и отсортированный список из первого массива и Сумма — это сумма Количества из первого массива для повторяющихся элементов имя.
E> Простейшее решение — сортируем массив по ключевому полю (в данном E>случае [Имя], после чего все повторяющиеся имена будут идти по порядку. E> Теперь пробегаемся по массиву — на каждом шаге, если значение E>ключевого поля такое же как и предыдущее — то накапливаем аккумулятор (в E>данном случае просто инкрементируем SUM), если нет — то выдаем E>[ПредыдущееИмя, SUM], зануляем аккумулятор, обновляем его текущим E>значением и идем дальше.
Здравствуйте, AntonAl, Вы писали:
AA>Здравствуйте, ettcat, Вы писали:
>>> Смысл такой: есть массив: [Имя , Количество] в котором Имя повторяется, надо сделать другой массив [Имя, Сумма], где Имя — уникальный и отсортированный список из первого массива и Сумма — это сумма Количества из первого массива для повторяющихся элементов имя.
E>> Простейшее решение — сортируем массив по ключевому полю (в данном E>>случае [Имя], после чего все повторяющиеся имена будут идти по порядку. E>> Теперь пробегаемся по массиву — на каждом шаге, если значение E>>ключевого поля такое же как и предыдущее — то накапливаем аккумулятор (в E>>данном случае просто инкрементируем SUM), если нет — то выдаем E>>[ПредыдущееИмя, SUM], зануляем аккумулятор, обновляем его текущим E>>значением и идем дальше.
AA>Вопрос как отсортировать?
Использовать в качестве таблицы двоичное дерево.
На С++ решалось бы примерно так:
vector<pair<string, int> > items;
map<string, int> sums;
for (auto it = items.begin(), end = items.end(); it != end; ++it)
sums[it->first] += it->second;
Как будет на VB — не знаю, к сожалению.
map даёт автоматическое упорядочивание.