Сортировка строк в таблице/списке значений с учетом регистра
Подскажите, пожалуйста, возможна ли реализация сортировки строк в таблице/списке значений с учетом регистра средствами платформы (методом Сортировать)?
Пока пришлось вывернуться, заменив не учитывающую регистр сортировку строк сортировкой кодов символов. Для этого помещаю в дополнительные колонки таблицы значений строки, соответствующие HEX-представлению сортируемых строк (сначала из строки получаем двоичные данные с кодировкой utf-8, затем из двоичных данных - HEXСтроку). Для строк на английском языке подходит, а вот с русскими буквами - будут проблемы с буквой ё.
В платформе есть параметр функции Сортировать Объект Сравнения, но его никак нельзя переопределить, задав собственное правило сравнения (подобно C++ или C#).
Пока пришлось вывернуться, заменив не учитывающую регистр сортировку строк сортировкой кодов символов. Для этого помещаю в дополнительные колонки таблицы значений строки, соответствующие HEX-представлению сортируемых строк (сначала из строки получаем двоичные данные с кодировкой utf-8, затем из двоичных данных - HEXСтроку). Для строк на английском языке подходит, а вот с русскими буквами - будут проблемы с буквой ё.
В платформе есть параметр функции Сортировать Объект Сравнения, но его никак нельзя переопределить, задав собственное правило сравнения (подобно C++ или C#).
По теме из базы знаний
- Обработки для просмотра таблиц, списков, справочников, документов, регистров. Групповая обработка справочников и документов.
- Лучшие методы сравнения таблиц значений
- Экселька. Универсальный инструмент, построенный по типу классических электронных таблиц, с возможностью использования данных 1С.
- Как автоматизировать учет по проектам в 1С:Бухгалтерии
- Как передать Таблицу Значений в Динамический Список?
Найденные решения
Решение прямо в лоб без заморочек с кодами символов и языками ценой удвоения длины исходной строки + цикл:
Функция СтрокаДляСортировкиСУчетомРегистра(Стр)
СтрСортировки = "";
Для Сч = 1 По СтрДлина(Стр) Цикл
Симв = Сред(Стр, Сч, 1);
Если Симв = НРег(Симв) Тогда
Суффикс = "1" // Нижний регистр либо регистронезависимый символ
Иначе
Суффикс = "2" // Верхний регистр
КонецЕсли;
СтрСортировки = СтрСортировки + Симв + Суффикс;
КонецЦикла;
Возврат СтрСортировки
КонецФункции
ПоказатьОстальные ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
Решение прямо в лоб без заморочек с кодами символов и языками ценой удвоения длины исходной строки + цикл:
Функция СтрокаДляСортировкиСУчетомРегистра(Стр)
СтрСортировки = "";
Для Сч = 1 По СтрДлина(Стр) Цикл
Симв = Сред(Стр, Сч, 1);
Если Симв = НРег(Симв) Тогда
Суффикс = "1" // Нижний регистр либо регистронезависимый символ
Иначе
Суффикс = "2" // Верхний регистр
КонецЕсли;
СтрСортировки = СтрСортировки + Симв + Суффикс;
КонецЦикла;
Возврат СтрСортировки
КонецФункции
Показать
(3) Михаил, спасибо за задачу. "Аутохакатон" был весьма познавательным, интересным и захватывающим. В итоге победил гибрид моего подхода и вашей реализации с одним грязным костылём. Если ограничиться только кириллицей, то лучше всего сработало это:
P.S. Сортировку в таблице делал по колонке с типом "Двоичные данные" - работает. Но можно и строку для сортировки увосьмеренного размера возвращать.
Функция ДДДляСортировкиСУчетомРегистра(Стр)
ДД = ПолучитьДвоичныеДанныеИзСтроки(Стр, "UTF-32BE");
Ст = Сред(ПолучитьHexСтрокуИзДвоичныхДанных(ДД), 5) + "0000";
Ст = СтрЗаменить(Ст, "04010000", "04150001"); //Ё
Ст = СтрЗаменить(Ст, "04510000", "04350001"); //ё
Возврат ПолучитьДвоичныеДанныеИзHexСтроки(Ст);
КонецФункции
ПоказатьP.S. Сортировку в таблице делал по колонке с типом "Двоичные данные" - работает. Но можно и строку для сортировки увосьмеренного размера возвращать.
(5) Сильно!
Но что-то Вы в конце увлеклись.
1. Преобразование в строку символов уже явно сделано в функции ПолучитьHexСтрокуИзДвоичныхДанных.
2. Затем элегантно поменяли местами (Swap) все половинки слов (восьмисимвольных подстрок), пользуясь тем, что все коды символов расположены в 0-й плоскости.
3. Затем переставили изменённые коды букв ё после соответствующих кодов букв е
Тут лучше остановиться.
Обратное преобразование в двоичные данные, как мне кажется, ничего не даст - сравниваться всё равно будут представления, т.е. платформа опять неявно сделает HEXСтроку, да ещё и с пробелами между байтами.
Но что-то Вы в конце увлеклись.
1. Преобразование в строку символов уже явно сделано в функции ПолучитьHexСтрокуИзДвоичныхДанных.
2. Затем элегантно поменяли местами (Swap) все половинки слов (восьмисимвольных подстрок), пользуясь тем, что все коды символов расположены в 0-й плоскости.
3. Затем переставили изменённые коды букв ё после соответствующих кодов букв е
Тут лучше остановиться.
Обратное преобразование в двоичные данные, как мне кажется, ничего не даст - сравниваться всё равно будут представления, т.е. платформа опять неявно сделает HEXСтроку, да ещё и с пробелами между байтами.
(7) Сегодня пришло время замера производительности разных вариантов.
У меня есть пример, в котором производится порядка 1126000 преобразований строк и порядка 160000 сортировок с ними(выходит, что в одной сортировке используется в среднем 7 преобразованных строк).
Все строки - на английском языке (наименования пространств имен и наименования атрибутов XML-файла).
Пробовал метод ПолучитьДвоичныеДанныеИзСтроки с разными кодировками (Windows-1251, utf-8, utf-16BE, utf-32BE) и с сортировкой двоичных данных.
Наибольшее время преобразования получилось для кодировки Windows-1251. Все остальные - где-то на 3-4% быстрее (независимо от разрядности, разброс времени в пределах погрешности измерений - около 1%). Время сортировки во всех случаях практически одно и то же.
Сравнил также производительность алгоритма при переводе полученных двоичных данных в строку методом ПолучитьHexСтрокуИзДвоичныхДанных и сортировке строк. Время преобразования строк при этом возрастает, а время сортировки - сокращается. Суммарные затраты времени на всё - выше в среднем на 12-15%.
В результате оставил в программе только ПолучитьДвоичныеДанныеИзСтроки с кодировкой utf-8 и сортировку двоичных данных.
У меня есть пример, в котором производится порядка 1126000 преобразований строк и порядка 160000 сортировок с ними(выходит, что в одной сортировке используется в среднем 7 преобразованных строк).
Все строки - на английском языке (наименования пространств имен и наименования атрибутов XML-файла).
Пробовал метод ПолучитьДвоичныеДанныеИзСтроки с разными кодировками (Windows-1251, utf-8, utf-16BE, utf-32BE) и с сортировкой двоичных данных.
Наибольшее время преобразования получилось для кодировки Windows-1251. Все остальные - где-то на 3-4% быстрее (независимо от разрядности, разброс времени в пределах погрешности измерений - около 1%). Время сортировки во всех случаях практически одно и то же.
Сравнил также производительность алгоритма при переводе полученных двоичных данных в строку методом ПолучитьHexСтрокуИзДвоичныхДанных и сортировке строк. Время преобразования строк при этом возрастает, а время сортировки - сокращается. Суммарные затраты времени на всё - выше в среднем на 12-15%.
В результате оставил в программе только ПолучитьДвоичныеДанныеИзСтроки с кодировкой utf-8 и сортировку двоичных данных.
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот