584 документа
← К списку

Удаляйте элементы с конца

страница

Удаляйте элементы с конца

И вот последний, четвертый, «секрет». Инструкция Для Каждого Цикл очень удобная и простая. Так и хочется ею пользоваться! Но тут главное – не переусердствовать. Потому что бывают задачи, когда элементы коллекции обязательно нужно перебирать в определенном порядке. Хотя, на первый взгляд, в этом нет никакой необходимости.

Чтобы все увидеть своими глазами, сделайте простой пример (листинг 7.16).

Листинг 7.1****6. Удалить все числа, которые меньше 10. Неправильный вариант

Числа = Новый Массив();

Числа.Добавить(10);

Числа.Добавить(8);

Числа.Добавить(4);

Числа.Добавить(15);

 

Для Каждого ТекущееЧисло Из Числа Цикл

Если ТекущееЧисло < 10 Тогда

Числа.Удалить(Числа.Найти(ТекущееЧисло));

 

КонецЕсли;

 

КонецЦикла;

Задача очень простая. У вас есть массив из четырех чисел. Вам нужно удалить из этого массива все числа, которые меньше 10.

Поставьте точку останова на инструкции Если и запустите проект в режиме отладки.

Не ожидая подвоха, вы написали Для Каждого Цикл, и дальше происходит вот что. На первой итерации цикла ТекущееЧисло у вас – 10 (рис. 7.180).

Рис. 7.1****80. Первая итерация цикла

На второй итерации цикла ТекущееЧисло у вас будет 8 (рис. 7.181).

Рис. 7.18****1. Вторая итерация цикла

И тут вы обнаруживаете, что этот элемент нужно удалить. Коллекции не терпят пустых мест. Как только вы его удаляете, остальные элементы коллекции перемещаются, чтобы занять освободившееся место (рис. 7.182).

Рис. 7.18****2. После удаления элемента 8

Получается, что на втором месте оказалось число 4, которое вы еще не обрабатывали. Но цикл продолжается, и на третьей итерации вы, естественно, переходите к следующему элементу коллекции (рис. 7.183).

Рис. 7.18****3. Третья итерация цикла

Теперь ваше текущее число 15. А 4 «проскочила» мимо вас. И осталась в массиве.

Если вспомнить, что вы представляли массив как стеллаж, то, когда вы удаляете один из мячиков, все остальные, которые находятся выше него, «проваливаются» вниз (рис. 7.184).

Рис. 7.18****4. Остальные мячики проваливаются вниз

И мячик, который вы должны были бы обработать на следующем шаге, проскакивает мимо вас.

Чтобы такого не случалось, нужно двигаться сверху вниз, то есть от конца к началу (рис. 7.185).

Рис. 7.18****5. Обход массива с конца

Тогда, если вы удалите элемент 4, вниз «провалится» элемент с той полки, которую вы уже обрабатывали, – 15. И это не страшно.

Как все то же самое сделать на встроенном языке? Довольно просто. Но для этого нужно будет использовать еще один вид инструкции цикла – Пока Цикл (листинг 7.17).

Листинг 7.1****7. Удалить все числа, которые меньше 10. Правильный вариант

ТекущийИндекс = Числа.ВГраница();

Пока ТекущийИндекс >= 0 Цикл

Если Числа[ТекущийИндекс] < 10 Тогда

Числа.Удалить(ТекущийИндекс);

 

КонецЕсли;

 

ТекущийИндекс = ТекущийИндекс - 1;

 

КонецЦикла;

В такой форме записи цикл выполняется до тех пор, пока выражение, записанное между Пока и Цикл, равно Истина. Как только это выражение становится равно Ложь, выполнение цикла прекращается.

Чтобы обходить цикл, вы создаете переменную ТекущийИндекс. В ней будет находиться индекс того элемента массива, который нужно обработать. Сначала вы помещаете в эту переменную индекс последнего элемента (листинг 7.18).

Листинг 7.1****8. Помещаете индекс самого последнего элемента

ТекущийИндекс = Числа.ВГраница();

В конце тела цикла вы каждый раз уменьшаете этот индекс на единицу. Это позволяет вам двигаться от конца к началу (листинг 7.19).

Листинг 7.1****9. Уменьшаете индекс на единицу

ТекущийИндекс = ТекущийИндекс – 1;

А в условии цикла вы проверяете, не стал ли текущий индекс отрицательным. Как только он становится меньше нуля, исполнение цикла завершается (листинг 7.20).

Листинг **7.**20. Проверяете, не стал ли текущий индекс отрицательным

Пока ТекущийИндекс >= 0 Цикл

Таким образом вы обходите все индексы от последнего к нулевому. Сделайте этот пример в своей конфигурации. Пройдите его в режиме отладки по шагам, посмотрите, как он работает. Убедитесь, что в результате в массиве останутся только два значения: 10 и 15.