Имя: Пароль:
IT
 
Как с удалением перебора коллекции в других языках программирования кроме 1с?
🠗 (Волшебник 31.05.2022 19:03)
0 Гений 1С
 
гуру
30.05.22
18:58
В 1с мы знаем что все очень печально, если внутри цикла перебора удалить элемент коллекции, перебор нарушается.
А как в других ЯП?
1 Ненавижу 1С
 
гуру
30.05.22
19:12
(0) в других языках уже есть готовые методы или удаляющие элементы коллекции или пропускающие их. В том числе ленивые вычисления
2 Злопчинский
 
30.05.22
19:19
а в обратном порядке перебрать коллекцию в снеговике так не получится?
3 Ненавижу 1С
 
гуру
30.05.22
19:35
4 H A D G E H O G s
 
30.05.22
19:59
(0) в других яп либо также, либо мудацкий сахар.
5 Гений 1С
 
гуру
30.05.22
20:00
(2) а в клюшках было разве Downto?
6 Гений 1С
 
гуру
30.05.22
20:01
(4) не разрушай мою веру в тру-программистов.
7 Ненавижу 1С
 
гуру
30.05.22
20:27
(4) циклы в целом мудацкий сахар тоже тогда.
Условный и безусловный переход рулят. Шутка
8 Garykom
 
гуру
30.05.22
20:37
(4) Эээ как бы не.
9 Garykom
 
гуру
30.05.22
20:38
Очень многие ЯП через foreach работают с коллекциями-перечислениями как с массивом ссылок и удаление одного никак не повлияет на последующие
Естественно не надо стрелять себе в ногу и попытаться после удаления обратиться к удаленному
Обычно эксепшен будет
10 mikecool
 
30.05.22
20:42
(0) что же тебя все печалит?
11 1Сергей
 
30.05.22
21:19
(10) он 1С-Гот
12 Ненавижу 1С
 
гуру
30.05.22
21:20
(0) погоди, ты же писал, что и плюсы и джаву и шара знаешь. Значит сам можешь рассказать
13 Asmody
 
30.05.22
21:22
(0) менять коллекцию, по которой ползет итератор, не рекомендуется ни в одном языке, где такое бывает.
14 Ненавижу 1С
 
гуру
30.05.22
21:24
(13) или нужен специальный итератор. В общем смысле паттерна
15 Asmody
 
30.05.22
21:27
И вообще, имьютабилити - наше всё
16 Гений 1С
 
гуру
31.05.22
14:28
(12) знаю, но только то, что нужно на практике. С удалением из коллекций не сталкивался.
17 СвинТуз
 
31.05.22
14:31
(0)
Везде одни и те же проблемы.
Нельзя пилить ветку на которой сидишь.
Обычно плохо оканчивается.
18 Garykom
 
гуру
31.05.22
14:33
(16) Ты заучи одну простую вещь:
Не надо удалять из коллекций - надо копировать нужные элементы в новую пустую коллекцию!
19 СвинТуз
 
31.05.22
14:36
Или идешь с конца,
или ищешь нужные к удалению и удаляешь,
или перекидываешь нужные в новую, а старую удаляешь.

Мы это в универе еще проходили. На Паскале.

Удивляет? )
Это же уровень института и школы.
Задачки из сборника.
20 СвинТуз
 
31.05.22
14:45
Пойти с начала и удалять ту на которой сидишь = ведет к изменению индексов еще пройденных строк.

Тогда если в этом направлении не "Для каждого ... Цикл" , а

Счетчик = 0;
Пока Счетчик >= Массив.Количество()-1 Цикл

Если Массив(Счетчик) = "Удалить" Тогда
Массив.Удалить(Счетчик);
Иначе
Счетчик = Счетчик+1;
КонецЕсли;

КонецЦикла


Писать можно по разному. В том числе и вычурно.
21 Ненавижу 1С
 
гуру
31.05.22
14:45
(19) или используешь правильный итератор правильно
22 Ненавижу 1С
 
гуру
31.05.22
14:45
23 СвинТуз
 
31.05.22
14:46
Счетчик = 0;
Пока Счетчик <= Массив.Количество()-1 Цикл

Если Массив(Счетчик) = "Удалить" Тогда
Массив.Удалить(Счетчик);
Иначе
Счетчик = Счетчик+1;
КонецЕсли;

КонецЦикла
24 СвинТуз
 
31.05.22
14:47
Нет смысла пенять на зеркало )
25 Kassern
 
31.05.22
14:51
(23) У массива есть замечательный метод ВГраница()
26 oslokot
 
31.05.22
15:13
(0) Вообще-то правильно собрать массив коллекции для удаления, а уж потом удалять
27 Garykom
 
гуру
31.05.22
15:21
(26) ненужная двойная обработка

почти всегда лучше и быстрее (18)
28 oslokot
 
31.05.22
15:22
(27) зато наглядно и в типовых такое сплошь и рядом
29 oslokot
 
31.05.22
15:23
(18) хотя да, копировать в другую тоже хорошо, встречал
30 Гений 1С
 
гуру
31.05.22
15:41
(20) так писать не стоит, непрозрачно. Лучше уж обратный цикл
Для инд = 1 по Всего Цикл
... Строка = ТЗ[Всего-Инд];
КонецЦикла;
31 Gary417
 
31.05.22
15:52
(9) вот как раз многие языки и не дают менять коллекцию по которой идет перебор
(18) а теперь задача на один грейд выше: размер коллекции 50 гигабайт
32 Gary417
 
31.05.22
15:53
(31) +и ты охренеешь создавать две коллекции по 50 чтобы чтото поудалять
33 1Сергей
 
31.05.22
15:53
(31) не могу представить кейс, когда такое может понадобиться
34 Gary417
 
31.05.22
15:56
(33) бывает такое я кровавом энтерпрайзе
вон я в мейле работал, там надо онлайн грузить данные по музыке и матчить по уже имеющимся метаданным, в памяти надо огромный кэш держать чтобы скорость была приемлемая и процедура сборки этого кэша минут 15 занимала..вот там как раз такие фокусы были с пересборкой массивов таких
35 1Сергей
 
31.05.22
15:57
кто бы знал что мейл на 1С построен...
36 Gary417
 
31.05.22
15:58
(35) я не про 1С, а про такие задачи
37 Gary417
 
31.05.22
15:58
в 1С тоже бывают большие объемы данных, но там всё решается 'ну ниче, вы подождете'...а бывает что подождете - нельзя. а память на сервере не бесконечная
38 mikecool
 
31.05.22
16:00
(30) а как тогда называется
Для инд = -Всего по 0 Цикл
... Строка = ТЗ[-Инд];
КонецЦикла;
39 Garykom
 
гуру
31.05.22
16:02
(32) 50 гб это уже не коллекция а База Данных
И там совсем другие методы, где реально не удаляются записи а просто "помечаются на удаление"
И потом делается шринк/вакуум (реструктуризация) который это дело чистит, причем обычно путем создания новой временной таблички куда данные копируются не удаленные и затем подменяется взамен исходной, которая грохается
40 СвинТуз
 
31.05.22
16:22
Это еще не непрозрачно. (30)

Счетчик = 0;
Пока Истина Цикл
Если Счетчик >= Массив.Количество()-1 Тогда
Перейти ~ВыходИзЦикла;
ИначеЕсли Массив(Счетчик) = "Удалить" Тогда
Массив.Удалить(Счетчик);
Иначе
Счетчик = Счетчик+1;
КонецЕсли;

КонецЦикла;
~ВыходИзЦикла:
41 СвинТуз
 
31.05.22
16:26
Счетчик = 0;
~Цикл:
Если Счетчик >= Массив.Количество()-1 Тогда
ИначеЕсли Массив(Счетчик) = "Удалить" Тогда
    Массив.Удалить(Счетчик);
    Перейти ~Цикл;
Иначе
    Счетчик = Счетчик+1;
    Перейти ~Цикл;
КонецЕсли;
42 1Сергей
 
31.05.22
16:27
(40) летс готу-срач беган
43 СвинТуз
 
31.05.22
16:28
~Цикл:
Счетчик = Массив.Количество()-1;
Если Счетчик <= 0 Тогда
ИначеЕсли Массив(Счетчик) = "Удалить" Тогда
    Массив.Удалить(Счетчик);
    Перейти ~Цикл;
Иначе
    Перейти ~Цикл;
КонецЕсли;
44 Gary417
 
31.05.22
16:29
(39) у меня был случай когда надо прям совсем рядом данные в памяти держать, и онлайн править кэш в процессе загрузки данных

ну 50гб это конечно я загнул, в моем случае гигабайт 10 было... но я чтобы описать потенциальную проблему 'перелить из массива в массив'
зачастую на больших объемах решать надо вопрос так чтобы сразу коллекция была такой чтобы её онлайн не править
45 1Сергей
 
31.05.22
16:29
(43) Проклято
46 dervishsy
 
31.05.22
16:30
(0)Ну например так :
List<Customer> customersWithMoreThan100Points = customers
(1)  .stream()
(2)  .filter(c -> c.getPoints() > 100)
(3)  .collect(Collectors.toList());

1. Для коллекции customers создаем объект типа Stream, который может итерироваться по коллекции.
2. Фильтруем по условию
3. Запихиваем то что осталось в коллекцию типа List.
47 Gary417
 
31.05.22
16:33
(45) это кстати та самая единственная причина когда goto оправдан
48 Gary417
 
31.05.22
16:33
(47) +я помню коллеге мозг сломал такой конструкцией ;)
49 СвинТуз
 
31.05.22
16:34
(45)
На машинном языке типа ассемблера программа будет одинаковой.
Цикл это лишь красивая обертка.
50 СвинТуз
 
31.05.22
16:36
Команда = "Массив.Удалить(Счетчик)";
~Цикл:
Счетчик = Массив.Количество()-1;
Если Счетчик <= 0 Тогда
ИначеЕсли Массив(Счетчик) = "Удалить" Тогда
    Выполнить(Команда);
    Перейти ~Цикл;
Иначе
    Перейти ~Цикл;
КонецЕсли;

(45)
51 Garykom
 
гуру
31.05.22
16:37
(47) Только потому что у Прервать() нет параметра сколько циклов прервать
52 Garykom
 
гуру
31.05.22
16:37
(51) подразумевается вложенных циклов
53 Kassern
 
31.05.22
16:44
Вот тут мнение 1с, по поводу оператора Перейти
https://its.1c.ru/db/v8std/content/547/hdoc
54 Kassern
 
31.05.22
16:45
как-то же справляются типовые конфы без этого оператора
55 1Сергей
 
31.05.22
16:47
(50) Как выйти из этого цикла? Только удалив всё?
56 Kassern
 
31.05.22
16:48
(55) легко и просто это делается на уровне платформы современной)) Она просто ругнется на бесконечный цикл и прервет его)
57 PLUT
 
31.05.22
16:48
(47) нетленка (опфускатор) тоже ~Перейти оправданно использует часто
58 Kassern
 
31.05.22
16:49
(57) там это один из основных механизмом обфускации кода.
59 Выпрь
 
31.05.22
16:49
А вот интересно ведь на ассеблере ничего кроме готу нет.
Почему вдруг решили что готу в более высоких языках - это плохо
60 PLUT
 
31.05.22
16:50
(57) найдите гота на фото

https://netlenka.org/Content/images/netlenka1c-hero.png
61 Kassern
 
31.05.22
16:50
это как метод Выполнить(кусок кода) для КД2. Там тоже это оправдано. Я же про обычные конфы для бизнеса. Там за глаза хватает штатных методов для работы. Без всяких гоуту
62 1Сергей
 
31.05.22
16:57
(50)

Массив = Новый Массив;
Массив.Добавить("Удалить");
Массив.Добавить("Оставить");

// Вэллком ту зависон
Команда = "Массив.Удалить(Счетчик)";
~Цикл:
Счетчик = Массив.Количество()-1;
Если Счетчик <= 0 Тогда
ИначеЕсли Массив(Счетчик) = "Удалить" Тогда
    Выполнить(Команда);
    Перейти ~Цикл;
Иначе
    Перейти ~Цикл;
КонецЕсли;
63 Kassern
 
31.05.22
17:00
(62) это прям квинтэссенция того, как делать не надо))
64 Asmody
 
31.05.22
17:01
65 Gary417
 
31.05.22
17:06
(59) уже больше 30 лет как нет 'того самого стремного' гоуту в языках выского уровня, народ его боится по привычке

чтобы понять почему это плохо, возьми программу на 5 млн строк на ассемблере и разберись в ней за сутки, хотябы в общих чертах что она делает, тогда поймешь почему гоуту плохо и в ассемблере и в остальных языках
66 PLUT
 
31.05.22
17:07
(65) то ли дело бесконечный цЫкл main() в Сях
67 Gary417
 
31.05.22
17:09
(66) а в чем проблема цикла main в сях? если я не ошибаюсь это жизненный цикл приложения как такового
68 СвинТуз
 
31.05.22
17:09
(55)
Намек на ошибку?
Перемудрил с "Счетчик"
69 СвинТуз
 
31.05.22
17:10
(63)
Не делать не значит не уметь делать
70 PLUT
 
31.05.22
17:20
(67)  ничего плохого

const int main[] = {
    -443987883, 440, 113408, -1922629632,
    4149, 899584, 84869120, 15544,
    266023168, 1818576901, 1461743468, 1684828783,
    -1017312735
};


3.14жжено отсюда https://tproger.ru/translations/main-is-usually-a-function-so-then-when-is-it-not/

когда погромисту делать нечего...
71 H A D G E H O G s
 
31.05.22
17:25
(66) Нет бесконечного цикла в сях.
Бесконечный цикл - это особенность жизненного цикла оконного приложения winAPI
72 PLUT
 
31.05.22
17:30
(71) бесконечного цЫкла нет, а void main() есть :) так исторически сложилось
73 Гений 1С
 
гуру
31.05.22
19:12
(38) ух ты, красиво
74 Ненавижу 1С
 
гуру
31.05.22
19:49
(73) пздц
75 ДедМорроз
 
31.05.22
23:06
Если обходится коллекция,которая представлена как связный список,то удаление элементов,кроме текущего,никак не влияет на перебор,хотя,при желании,можно сделать так,что и текущий удалять можно.
Если коллекция массив,то удаление можно делать с коррекцией индекса,на Си это элементарно.
Вот с добавлением в середину намного сложнее,т.к.сделать,чтобы добавленные обходились,не так уж и просто.
И потом,тут все от логики кода зависит,иногда нужно обходить добавленные,а иногда - нет.