Удивительные коллекции 1С
Заметка о некоторых особенностях работы с коллекциями в 1С.
1. Удаление данных из массива по условию
По умолчанию примем тот факт, что порядок следования элементов после удаления должен соответствовать порядку до удаления.
Для удаления не подходит обход коллекции циклом Для каждого
, так как коллекции в 1С обладают свойством неявного сдвига элементов при удалении. Поэтому, удаляя элемент массива в цикле Для каждого
, получим, что цикл будет перескакивать некоторые элементы, которые сдвинулись на место удаленного.
Обычно удаляют элементы из массива следующим способом:
Для ОбратныйИндекс = -Массив.ВГраница() По 0 Цикл
Индекс = -ОбратныйИндекс;
Если НЕ Массив[Индекс] = 3 Тогда
Массив.Удалить(Индекс);
КонецЕсли;
КонецЦикла;
Проблема этого метода: после удаления элемента из массива, элементы, следующие за ним, платформа "под капотом" передвигает на один индекс назад, таким образом получаем цикл в цикле.
Создавать еще одну коллекцию, куда мы запишем только "правильные" элементы, неудовлетворяющие условию удаления, а затем просто удалить исходный массив - чревато избыточным потреблением памяти.
Поэтому обходим массив, передвигая соответствующие отбору элементы в начало массива после последнего "правильного" элемента:
Индекс = -1;
Для Каждого ПроверяемыйЭлемент Из Массив Цикл
// Условие для сохраняемых элементов. Остальные будут удалены.
Если ПроверяемыйЭлемент = 3 Тогда
// Переносим текущий элемент в начало массива
Индекс = Индекс + 1;
Массив[Индекс] = ПроверяемыйЭлемент;
КонецЕсли;
КонецЦикла;
// Оставшиеся элементы в конце массива удаляем
Пока Массив.ВГраница() > Индекс Цикл
Массив.Удалить(Массив.ВГраница());
КонецЦикла;
2. Уникальные значения в массиве (сгруппировать массив)
Если нам не важен порядок следования элементов в массиве после группировки, то циклом проходим элементы массива, вставляя их в ключи соответствия, затем циклом составляем массив из ключей соответствия.
Если порядок следования важен, сперва составляем соответствие количества вхождений элементов в массиве и, используя метод удаления из п.1, удаляем те элементы, у которых количество вхождений больше 1.
3. Соответствие уникальных значений с подсчетом (группировкой) значений
Логика создания такой коллекции заключается в задании уникальным ключам коллекции со значениями этих ключей. Для решения этой задачи подходит Соответствие, где значениями будет наполняемый массив.
МассивСтруктур = Новый Массив;
ЭлементМассива = Новый Структура("ИмяИндекса, Значение", "Красный", "Кросовки");
МассивСтруктур.Добавить(ЭлементМассива);
ЭлементМассива = Новый Структура("ИмяИндекса, Значение", "Синий", "Кросовки");
МассивСтруктур.Добавить(ЭлементМассива);
ЭлементМассива = Новый Структура("ИмяИндекса, Значение", "Красный", "Куртка");
МассивСтруктур.Добавить(ЭлементМассива);
ЭлементМассива = Новый Структура("ИмяИндекса, Значение", "Желтый", "Кепка");
МассивСтруктур.Добавить(ЭлементМассива);
Коллекция = Новый Соответствие;
Для каждого Элемент Из МассивСтруктур Цикл
НайденноеЗначение = Коллекция.Получить(Элемент.ИмяИндекса);
Если НайденноеЗначение = Неопределено Тогда
НайденноеЗначение = Новый Массив;
КонецЕсли;
НайденноеЗначение.Добавить(Элемент.Значение);
Коллекция.Вставить(Элемент.ИмяИндекса, НайденноеЗначение);
КонецЦикла;
Таким образом мы получаем сгруппированную коллекцию. Чтобы получить количество значений у нужного ключа вызовем метод "Количество()" у значения элемента коллекции
4. Таблица значений на клиенте
Таблица значений на клиенте может существовать и даже прекрасно работают все методы, включая индексирование. Но вот передавать ее по клиент-серверному взаимодействию не представляется возможным.
Чтобы создать таблицу значений на клиенте, можно выполнить следующий код:
Описание = Новый ОписаниеТипов("ТаблицаЗначений");
Таблица = Описание.ПривестиЗначение();
Комментарии
Отправить комментарий