Сортировка строк в таблице/списке значений с учетом регистра

1. gml 05.11.24 21:13 Сейчас в теме
Подскажите, пожалуйста, возможна ли реализация сортировки строк в таблице/списке значений с учетом регистра средствами платформы (методом Сортировать)?
Пока пришлось вывернуться, заменив не учитывающую регистр сортировку строк сортировкой кодов символов. Для этого помещаю в дополнительные колонки таблицы значений строки, соответствующие HEX-представлению сортируемых строк (сначала из строки получаем двоичные данные с кодировкой utf-8, затем из двоичных данных - HEXСтроку). Для строк на английском языке подходит, а вот с русскими буквами - будут проблемы с буквой ё.
В платформе есть параметр функции Сортировать Объект Сравнения, но его никак нельзя переопределить, задав собственное правило сравнения (подобно C++ или C#).
По теме из базы знаний
Найденные решения
2. lmnlmn 69 05.11.24 23:12 Сейчас в теме
Решение прямо в лоб без заморочек с кодами символов и языками ценой удвоения длины исходной строки + цикл:
Функция СтрокаДляСортировкиСУчетомРегистра(Стр)
	СтрСортировки = "";
	
	Для Сч = 1 По СтрДлина(Стр) Цикл
		Симв = Сред(Стр, Сч, 1);
		
		Если Симв = НРег(Симв) Тогда
			Суффикс = "1" // Нижний регистр либо регистронезависимый символ
		Иначе
			Суффикс = "2" // Верхний регистр
		КонецЕсли;
		
		СтрСортировки = СтрСортировки + Симв + Суффикс;
	КонецЦикла;
	
	Возврат СтрСортировки

КонецФункции
Показать
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. lmnlmn 69 05.11.24 23:12 Сейчас в теме
Решение прямо в лоб без заморочек с кодами символов и языками ценой удвоения длины исходной строки + цикл:
Функция СтрокаДляСортировкиСУчетомРегистра(Стр)
	СтрСортировки = "";
	
	Для Сч = 1 По СтрДлина(Стр) Цикл
		Симв = Сред(Стр, Сч, 1);
		
		Если Симв = НРег(Симв) Тогда
			Суффикс = "1" // Нижний регистр либо регистронезависимый символ
		Иначе
			Суффикс = "2" // Верхний регистр
		КонецЕсли;
		
		СтрСортировки = СтрСортировки + Симв + Суффикс;
	КонецЦикла;
	
	Возврат СтрСортировки

КонецФункции
Показать
3. gml 06.11.24 21:49 Сейчас в теме
(2) Спасибо, применю при сортировке русских букв. Надо будет померить скорость работы Вашего метода в сравнении с двумя вызовами встроенных функций.
4. lmnlmn 69 07.11.24 13:33 Сейчас в теме
(3) Если уж участвовать в соревновании с системными функциями, то надо не столь академичный вариант кода использовать. Нужно все это приправить костылями и грязными хаками. Аж самому интересно стало. Чуть позже выложу вариант для состязаний.
5. lmnlmn 69 07.11.24 16:57 Сейчас в теме
(3) Михаил, спасибо за задачу. "Аутохакатон" был весьма познавательным, интересным и захватывающим. В итоге победил гибрид моего подхода и вашей реализации с одним грязным костылём. Если ограничиться только кириллицей, то лучше всего сработало это:
Функция ДДДляСортировкиСУчетомРегистра(Стр)
	
	ДД = ПолучитьДвоичныеДанныеИзСтроки(Стр, "UTF-32BE");
	Ст = Сред(ПолучитьHexСтрокуИзДвоичныхДанных(ДД), 5) + "0000";
	Ст = СтрЗаменить(Ст, "04010000", "04150001"); //Ё
	Ст = СтрЗаменить(Ст, "04510000", "04350001"); //ё

	Возврат ПолучитьДвоичныеДанныеИзHexСтроки(Ст);
	
КонецФункции
Показать

P.S. Сортировку в таблице делал по колонке с типом "Двоичные данные" - работает. Но можно и строку для сортировки увосьмеренного размера возвращать.
6. gml 07.11.24 20:47 Сейчас в теме
(5) Сильно!
Но что-то Вы в конце увлеклись.
1. Преобразование в строку символов уже явно сделано в функции ПолучитьHexСтрокуИзДвоичныхДанных.
2. Затем элегантно поменяли местами (Swap) все половинки слов (восьмисимвольных подстрок), пользуясь тем, что все коды символов расположены в 0-й плоскости.
3. Затем переставили изменённые коды букв ё после соответствующих кодов букв е

Тут лучше остановиться.
Обратное преобразование в двоичные данные, как мне кажется, ничего не даст - сравниваться всё равно будут представления, т.е. платформа опять неявно сделает HEXСтроку, да ещё и с пробелами между байтами.
7. lmnlmn 69 07.11.24 20:53 Сейчас в теме
(6) Вообще да, но размера строк для сортировки в ТЗ испугался))
8. gml 08.11.24 20:37 Сейчас в теме
(7) Сегодня пришло время замера производительности разных вариантов.
У меня есть пример, в котором производится порядка 1126000 преобразований строк и порядка 160000 сортировок с ними(выходит, что в одной сортировке используется в среднем 7 преобразованных строк).
Все строки - на английском языке (наименования пространств имен и наименования атрибутов XML-файла).

Пробовал метод ПолучитьДвоичныеДанныеИзСтроки с разными кодировками (Windows-1251, utf-8, utf-16BE, utf-32BE) и с сортировкой двоичных данных.
Наибольшее время преобразования получилось для кодировки Windows-1251. Все остальные - где-то на 3-4% быстрее (независимо от разрядности, разброс времени в пределах погрешности измерений - около 1%). Время сортировки во всех случаях практически одно и то же.

Сравнил также производительность алгоритма при переводе полученных двоичных данных в строку методом ПолучитьHexСтрокуИзДвоичныхДанных и сортировке строк. Время преобразования строк при этом возрастает, а время сортировки - сокращается. Суммарные затраты времени на всё - выше в среднем на 12-15%.

В результате оставил в программе только ПолучитьДвоичныеДанныеИзСтроки с кодировкой utf-8 и сортировку двоичных данных.
9. lmnlmn 69 08.11.24 22:57 Сейчас в теме
(8) Спасибо что поделились результатами. Когда замерял разные варианты тоже подобную тенденцию заметил. "Внутриплатформенные" преобразования работают быстрее, даже если это одна две команды на языке 1С были.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот