Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Как удалить элемент из вектора в цикле? (http://www.flasher.ru/forum/showthread.php?t=207227)

darkthor 02.04.2014 16:17

Как удалить элемент из вектора в цикле?
 
Всем привет. В общем-то вопрос наверное простой. Но для меня, как новичка, этот момент немного напряг. Можно ли удалить элемент из вектора во время цикла по этому вектору?

Код AS1/AS2:

for each (var item:MyItem in items) {
  items.splice(items.indexOf(item), 1);
}

Получается что так делать нельзя. Но тогда как правильно?
Что делать если не все элементы нужно удалить? И если не знаешь какие надо удалять пока цикл по ним не сделаешь.

KBAC 02.04.2014 16:48

Код AS3:

items.splice(0, items.length);


darkthor 02.04.2014 17:11

я же написал:
Что делать если не все элементы нужно удалить? И если не знаешь какие надо удалять пока цикл по ним не сделаешь.

Добавлено через 1 минуту
Дело в том что при splice индексы смещаются и следующий ход цикла перескакивает через элемент.
delete тоже не подходит, так как пустой элемент все равно остается.

KBAC 02.04.2014 17:13

Код AS3:

for (var i:int = 0; i < items.length; i++)
{
    if (checkItem(items[i])) //если нужно удалять
    {
        items.splice(i, 1);
        i--;
    }
}


darkthor 02.04.2014 17:58

Так не работает. Говорю еще раз: при splice индексы смещаются и следующий ход цикла перескакивает через элемент.

Если не понятно, получается такая ситуация:
1. В векторе 2 элемента. [0] = a, [1] = b.
2. for берет элемент [0] = a
3. splice удаляет [0] = a. Теперь [0] = b.
4. for ищет элемент [1], но такого уже нет.

В результате [1] = b вообще не был обработан.

KBAC 02.04.2014 18:15

Для этого
Код AS3:

i--;

в коде

darkthor 02.04.2014 18:32

Извиняюсь, тупанул. Попробую так. Хотя выглядит как-то немного костылёво. Спасибо.

Tails 02.04.2014 19:11

Вызывать каждый раз splice может быть накладно.
Вот скоростной вариант:
Код AS3:

var lenght:uint                                 = items.length;
var currentIndex:uint                        = 0;
var i:uint;
var item:ItemObject;
for (i = 0; i < lenght; i++)
{
        item                                        = items[i];
 
 
        // Тут производим действия над элементом
        // ...
 
        if (checkItem(items[i])) //если нужно удалять
    {
                items[i]                        = null;
        continue;
    }
 
        // Сдвиг текущих элементов в списке, если предыдущие были удалены.
        if (currentIndex != i)
        {
                items[currentIndex] = item;
                items[i]                        = null;
        }
        currentIndex++;
}
 
// Обрезание списка от отработанных элементов
if (lenght != currentIndex)
        items.length                        = currentIndex;

На основе класса Juggler (Starling)

darkthor 02.04.2014 19:56

Интересный вариант. Спасибо. возьму на заметку для тяжелых мест. но пока у меня предполагается 3-4 элемента в векторе.

Добавлено через 4 минуты
Хочу еще добавить аргумент против вот этой конструкции:
Код AS1/AS2:

items.splice(items.indexOf(item), 1);

Если indexOf вернет -1 (элемент не найден) -- то удалится последний элемент. Что неприемлемо. Так что в таком случае все равно надо использовать if

dimarik 03.04.2014 23:42

Цитата:

Сообщение от Tails (Сообщение 1162835)
Вот скоростной вариант:
Код AS3:

var lenght:int = items.length;


Немного смущает размерность (тип int) свойства length. С вашей (или Даниэля?) легкой руки брюки превращаются в элегантные шорты и теряют одну степень двойки. И ставят нас в тупик отрицательными значениями при определенных условиях. Надеюсь, что вы не пишете ПО для космоса и АЭС ).


Часовой пояс GMT +4, время: 20:43.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.