Имя: Пароль:
1C
 
Как отсортировать коллекцию по полю без Таблицы Значений
Ø (Волшебник 30.08.2024 10:14)
0 Гений 1С
 
гуру
25.08.24
16:23
Можно через представление списка значений, но кривовато....
1 Гений 1С
 
гуру
25.08.24
16:25
Можно пузырьком, но тоже так себе
2 Гений 1С
 
гуру
25.08.24
19:41
В общем, ладно, сделал так, может подрастающее поколение сообразит чего для клиента:
Функция СортироватьКоллекциюПоПолю(Коллекция, ИмяПоля, Порядок = "Возр")
	ТЗ = Новый ТаблицаЗначений();
	ТЗ.Колонки.Добавить("Значение");
	ТЗ.Колонки.Добавить("Порядок");
	Для Каждого Элемент Из Коллекция Цикл
		НСтр = ТЗ.Добавить();
		НСтр.Значение = Элемент;
		НСтр.Порядок = Элемент[ИмяПоля];
	КонецЦикла;
	ТЗ.Сортировать("Порядок " + Порядок);
	Возврат ТЗ.ВыгрузитьКолонку("Значение");
КонецФункции
3 PR
 
25.08.24
16:52
(0) Нахрена?
4 Chameleon1980
 
25.08.24
17:01
я уж думал - новый "гениальный" метод сортировки
5 Chameleon1980
 
25.08.24
17:02
что сортировать из коллекций то понадобилось, у кого нет своей сортировки? и главное (3)
6 SleepyHead
 
гуру
25.08.24
17:12
7 Chameleon1980
 
25.08.24
17:34
как-то странно или я не правильно читаю:

"Как отсортировать коллекцию по полю без Таблицы Значений"

...ТЗ = Новый ТаблицаЗначений()...
8 SleepyHead
 
гуру
25.08.24
17:40
(7) Хочет сделать сортировку коллекции на клиенте, скорее всего.
9 PR
 
25.08.24
17:43
(7) Что непонятного-то
Не хватило сил у лошадки без ТЗ
10 Chameleon1980
 
25.08.24
17:47
(8) с тз на клиенте?
11 SleepyHead
 
гуру
25.08.24
17:52
(10) Насколько я понял - автор хочет сортировать на клиенте. Способа сделать это не нашел и сделал процедуру на сервере, которая копирует коллекцию в ТЗ и ее сортирует. И высказывает пожелание "может подрастающее поколение сообразит чего для клиента".

Судя по тексту процедуры, сортировать на клиенте хочет массив. Что в массиве - не указано. Непонятно, есть ли там ссылочные типы.
12 Chameleon1980
 
25.08.24
18:01
(11) спасибо - дошло. Привык к "гениальным идеям", а не к просьбе о помощи - потому неверно прочитал.
13 craxx
 
25.08.24
18:34
(9) Без ТЗ всё ХЗ ))))
14 Гений 1С
 
гуру
25.08.24
21:10
(11) в массиве конкретно у меня ключи записей регистра сведений, но могут быть структуры
15 RomanYS
 
25.08.24
22:57
(2) Чем это лучше (0) ?
С СЗ на сервер ходить не надо
16 Aleksey
 
26.08.24
02:49
Вроде раньше было модно такое через запрос делать, передавая коллекцию в качестве параметра
17 Ivan_495
 
26.08.24
03:20
посмотреть sql профайлер и оптимизировать
18 lEvGl
 
гуру
26.08.24
09:21
(16) не все коллекции одинаково полезны и могут быть переданы
некоторые только с выгрузкой в ТЗ, что нарушает начальное условие, но пейсанины все же меньше
19 Ненавижу 1С
 
гуру
29.08.24
09:31
длинновато, но только на клиенте:

Функция ОтсортированнаяКоллекцияПоПолю(Коллекция, ИмяПоля, Знач ПорядокСортировки = Неопределено) Экспорт
    
    Если ПорядокСортировки=Неопределено Тогда
        ПорядокСортировки = НаправлениеСортировки.Возр;    
    КонецЕсли;
    
    Соответствие = Новый Соответствие;
    СписокСортировки = Новый СписокЗначений;
    МассивКлючаНеопределено = Новый Массив;
    
    Для Каждого Элемент Из Коллекция Цикл
        Значение = Элемент[ИмяПоля];
        Если Значение=Неопределено Тогда
            МассивЗначенийКлюча = МассивКлючаНеопределено;
        Иначе            
            МассивЗначенийКлюча = Соответствие[Значение];
        КонецЕсли;
        
        Если МассивЗначенийКлюча=Неопределено Тогда
            МассивЗначенийКлюча = Новый Массив;
            Соответствие[Значение] = МассивЗначенийКлюча;
            СписокСортировки.Добавить(Значение);
        КонецЕсли;
        МассивЗначенийКлюча.Добавить(Элемент);
    КонецЦикла;
    
    СписокСортировки.СортироватьПоЗначению(ПорядокСортировки);
    
    Результат = Новый Массив;
    Для каждого Элемент Из СписокСортировки Цикл
        Значение = Элемент.Значение;
        Если Значение=Неопределено Тогда
            МассивЗначенийКлюча = МассивКлючаНеопределено;
        Иначе            
            МассивЗначенийКлюча = Соответствие[Значение];
        КонецЕсли;
        
        Для каждого ЭлМассива Из МассивЗначенийКлюча Цикл
            Результат.Добавить(ЭлМассива);
        КонецЦикла;
    КонецЦикла;
    
    Возврат Результат;
    
КонецФункции
20 Гений 1С
 
гуру
29.08.24
10:04
(19) принцип поясни, сложновато.
21 Ненавижу 1С
 
гуру
29.08.24
10:11
(20) Строится список значений по полю сортировки и соответствие с ключами поля сортировки и значениями - массивами элементов им соответствующими.
Список сортируется и перебирается, вытягиваются элементы из соответствия.
Приходится отдельно обрабатывать случай значения Неопределено, т.к. соответствия не могут содержать его как ключ.
22 Галахад
 
гуру
29.08.24
10:19
У результат нет ключей, только значения.
23 Мультук
 
гуру
29.08.24
10:24
(19)

На входе некая абстрактная коллекция, а на выходе всё-равно "массив"

Я не цепляюсь, я скорее печалюсь об ограничениях языка.


(20)
А чего тут сложного, тут даже думать не нужно, всё очевидно.
Кроме лайфхака с неопределено.
24 Ненавижу 1С
 
гуру
29.08.24
10:29
(23) 1. Есть такое. Но ленивые вычисления в 1с пока не завезли.
2. Это ж гений
25 SleepyHead
 
гуру
29.08.24
12:04
(0)

Я так понимаю, на клиенте хочется сортировать, потому что работаешь в форме

А что мешает передать твою коллекцию в процедуру на сервере без контекста, там отсортировать таблицей значений и вернуть результат?

Расход памяти будет минимальный.

Откуда вообще требование сортировать именно на клиенте? Очень сомневаюсь, что на клиенте сможешь отсортировать значения в коллекции так, как тебе надо, если там ссылочный тип.
26 lodger
 
29.08.24
12:20
(25) вытащить из ссылки гуид, конвертить в строку, сортировать. положить обратно ссылку.
27 SleepyHead
 
гуру
29.08.24
12:40
(26) А что, если надо по наименованию?
28 Волшебник
 
29.08.24
12:40
(26) сортировать по ссылке? чё, серьёзно?
29 PR
 
29.08.24
13:04
(28) Сортировка по ссылке имеет только один прикладной смысл, если нужно регистраторы регистра отсортировать по хронологии после сортировки по периоду
Все остальное — это дичь какая-то
30 Волшебник
 
29.08.24
14:10
(29) если нужно регистраторы регистра отсортировать по хронологии, то сортировать надо по дате.

сортировка по ссылке — это дичь сама по себе
31 Garykom
 
гуру
29.08.24
14:29
32 Волшебник
 
29.08.24
14:47
(31) Самому сортировать? Да ну нафиг... Есть же ТЗ.Сортировать()
33 PR
 
29.08.24
14:59
(30) Конечно же по дате
Но потом по ссылке
Потому что в одной секунде может быть много регистраторов
34 PR
 
29.08.24
15:01
Вот еще момент

https://its.1c.ru/db/metod8dev/content/2427/hdoc

"При работе со списками динамического просмотра следует учитывать то, что система неявным образом дополняет упорядочивание, установленное разработчиком прикладных решений или пользователем. Это делается для того, что бы избежать неоднозначности в упорядочивании объектов. Это касается также и упорядочивания по умолчанию, приведенного в таблице. Например, при упорядочивании справочника по полю Наименование система дополнит упорядочивание полем Ссылка, что позволит избежать неоднозначности при упорядочивании элементов справочника с одинаковыми наименованиями."

"К списку упорядочивания прибавляется упорядочивание по ссылке на регистратор и номеру строки. Следует отметить, что система дополняет список упорядочивания именно упорядочиванием по ссылке на регистратор. Это не то же самое, что упорядочивание по полю Регистратор, которое может быть выбрано пользователем в окне "Отбор и сортировка". При выборе поля Регистратор пользователем (или при установке такого порядка разработчиком прикладного решения) результат будет совсем другой - будет выполнено упорядочивание по регистраторам в порядке их даты и, кроме того, такое упорядочивание не может быть эффективным (механизм динамического просмотра списков не будет задействован). Любое упорядочивание по полям не базовых типов приводит к неэффективности упорядочивания, что описано ниже."
35 Garykom
 
гуру
29.08.24
15:07
(32) А простой способ Массив в ТЗ уже в платформе 1С завезли?
Без ручного цикла...
36 Волшебник
 
29.08.24
15:09
(35) ТЗ.ЗагрузитьКолонку(<Массив>, <Колонка>)
37 Garykom
 
гуру
29.08.24
16:00
(36) И оно добавит нужное число строк?
38 Волшебник
 
29.08.24
16:24
(37) хосподя...

	тз = Новый ТаблицаЗначений;
	тз.Колонки.Добавить("Имя");
	
	м = Новый Массив;
	м.Добавить("Иван");
	м.Добавить("Петр");
	м.Добавить("Фрося");
	
	Для н=1 По м.Количество() Цикл
		с = тз.Добавить();
	КонецЦикла; 
	
	тз.ЗагрузитьКолонку(м,"Имя");
39 Garykom
 
гуру
29.08.24
16:30
(38)
А простой способ Массив в ТЗ уже в платформе 1С завезли?
Без ручного цикла...
40 Garykom
 
гуру
29.08.24
16:32
(38) В данном случае ЗагрузитьКолонку лишнее
Один фиг цикл, не проще в нем сразу значение в строку писать?
41 Волшебник
 
29.08.24
16:37
(40) или так...
42 Garykom
 
гуру
29.08.24
16:41
(41) Лучше бы допилили платформу чтобы
ТЗ.ЗагрузитьКолонку(Массив, АвтодобавлениеСтрок = Ложь)
43 Волшебник
 
29.08.24
16:43
(42) Можно же написать свою функцию.
Кстати, именно поэтому в платформе нет функции ABS(), которая считает модуль числа, потому что она пишется в одну строчку двумя способами.
44 AAA
 
29.08.24
18:07
(43)По этой логике Мин и Макс тоже можно было не реализовывать в платформе )
45 Волшебник
 
29.08.24
18:06
(44) Там переменное число аргументов
46 Garykom
 
гуру
29.08.24
18:37
(45) Кто мешает в коде реализовать мин и макс для массива?
И да.
Такие функции были бы реально полезны и удобны.
Найти минимальный или максимальный элемент массива.
Упс у нас сортировки массива нет - чтобы первый и последний взять.
47 lEvGl
 
гуру
29.08.24
22:10
запрос же, в частном случае это не объект "ТЗ", т к ни одна из его перегрузок не используется
48 Волшебник
 
29.08.24
22:22
(46) Получится уродский код.

м = Новый Массив();
м.Добавить(1);
м.Добавить(2);
м.Добавить(3);
МинЗнач = Мин(м);


вместо изящного
МинЗнач = Мин(1,2,3);
49 Garykom
 
гуру
29.08.24
22:31
(48) А пойти чуть дальше и по аналогии со структурами в конструктор массива добавить
м = Новый Массив(1, 2, 3);

Тогда будет изящнейше
МинЗнач = Мин(Новый Массив(1, 2, 3));

Но при офигенной универсальности и удобстве
50 Garykom
 
гуру
29.08.24
22:34
(48) Не против оставить старый вариант функций мин/макс
Но насыпьте сахару для удобства, чтобы параметром можно было передать массив или еще что
51 Garykom
 
гуру
29.08.24
22:36
И разрешить объявлять свои функции/процедуры с переменным числом аргументов ))
52 lEvGl
 
гуру
29.08.24
22:44
субд рулит, умеет, могёт
и уже давно
https://dzen.ru/a/YGAR9w_Stw_wdTfr?ysclid=m0fozeb45v780251991
эти ручно**очества только подтверждают несостоятельность инакомысляших архитектур
53 Garykom
 
гуру
29.08.24
22:45
(52) сам знаю как запросом 1С отсортировать переданный массив только через дикое извращение
или ты о чем?
54 lEvGl
 
гуру
30.08.24
05:04
(53) ТЗ, ТЧ передается в запрос, зачем массив? зачем извращения

типа первые 1 из массив или еще что то в этом роде

нет, Субэдэй к такому не готов
вобще это кажется возможным - сортировать массив в запросе
можно включить профайлер и увидеть что то вроде In
там будет запрос in(Select * from ttable sort by)
думается что это хрень, не занимался, и не стоит
55 TormozIT
 
гуру
29.08.24
22:49
(49) "Новый Массив(1, 2, 3)" уже занято (сейчас работает) - создает 3-х мерный массив размерностями 1х2х3
56 Гений 1С
 
гуру
30.08.24
10:04
(21) Опять окелло промахнулся... а что будет если на вход подать массив и попросить отсортировать по полю а:
[{а=1, б=2},{а=1, б=3},{а=2, б=4}]
Теоретики плохо умеют в практику, вангую на выходе получить:
[{а=1, б=2},{а=2, б=4}]
57 Ненавижу 1С
 
гуру
30.08.24
10:10
(56) ты проверил или "вангуешь"? Если второе - пройдите на три буквы
58 Гений 1С
 
гуру
30.08.24
10:12
(56) Хотя нет, был не прав, этот мазохист хранит массив значений ключа. Не, у меня бы не хватило ботанизма написать такой код, звеняйте...
Программист всегда исправляет последнюю ошибку.