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

как удалить определенные элементы из моего массива, состоящего из сотен элементов?

-eg:

var myArray:Array = ["dog", "cat", "bear", "duck", "frog", etc..., etc...];

Что мне делать, когда я хочу удалить «утку» из этого массива? Пожалуйста, имейте в виду, что массив очень длинный, и мы не знаем, ГДЕ находится "утка", поэтому мы не знаем ее индекс в массиве. Мне нужно каким-то образом получить этот элемент по его имени и удалить его из массива.


person Community    schedule 25.03.2013    source источник
comment
@Peter Я надеюсь, что содержимое массива представляет собой строки, если да, процитируйте их. На данный момент лучший способ кажется первым: var i: int = myArray.indexOf(duck); (если строка делает утку "уткой") и добавьте ответ Ильи следующим образом: if(i›=0)myArray.splice(i,1);   -  person Ihsan    schedule 25.03.2013


Ответы (4)


Это прямой способ сделать это:

Нестабильная версия (меньше копирует).

for (var i:int, j:int = array.length - 1, temp:Object; i <= j;) {
    temp = array[i];
    if (temp == "duck") {
        array[i] = array[j];
        array[j] = temp;
        j--;
    } else {
        i++;
    }
}
array.length = i;

И стабильная версия (больше копирования, но порядок исходного массива не изменился):

for (var i:int, j:int, temp:Object; i < array.length; i++) {
    temp = array[i];
    if (temp != "duck") {
        array[j] = temp;
        j++;
    }
}
array.length = j;

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

Алгоритм был бы существенно другим, если бы массив был отсортирован, потому что вы могли бы использовать двоичный поиск, чтобы найти элемент, который нужно удалить. В некоторых очень специфических ситуациях, как, например, если у вас есть хорошо обоснованный набор (который является вашим массивом), удаление будет еще проще, потому что положение искомого элемента может быть определено за постоянное время. Последнее можно смягчить за счет использования индексов (просто говоря, у вас может быть хэш-таблица, которая использует элементы массива в качестве ключей и их смещения в массиве в качестве значений).

Опять же, вам нужно рассмотреть все эти случаи и то, что практично в отношении вашей программы.

Как я упоминал выше, могут быть преимущества, если вы используете другую структуру данных, или если вы сортируете при вставке, или если вы индексируете при вставке.

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

person Community    schedule 25.03.2013

Если ваш массив очень длинный, его стоит как-то оптимизировать.

некоторые варианты:

1) пользоваться словарем; строка может быть ключом. Это имеет дополнительное преимущество, заключающееся в том, что ваш список не переиндексируется при добавлении/удалении элементов.

//specify weak keys when you create the dictionary
var myDictionary:Dictionary = new Dictionary(true);
//when you want to delete an item:
myDictionary["duck"] = null;

2) отсортируйте свой массив и используйте двоичный поиск. В Интернете много информации о бинарном поиске. Вот один ТАК вопрос по теме.

person mfa    schedule 25.03.2013
comment
из ответа: Это только упрощает код и, вероятно, будет неоптимальной производительностью. - person mfa; 25.03.2013
comment
@mfa Запуск массива в обратном направлении (от length-1 до нуля) более оптимален и не заботится об изменении длины. - person Vesper; 25.03.2013
comment
удален вариант №3; люди не читают, что это не оптимально - person mfa; 25.03.2013

Один из способов — просто использовать цикл while в сочетании с методом indexOf массива как такового:

var index:int;
while ((index = myArray.indexOf("duck")) >= 0)
{
    myArray.splice(index,1);
}

Вы можете обернуть это в функцию и принять параметры Array и String и вернуть результирующий массив следующим образом:

function removeSearchString(sourceArray:Array, searchString:String):Array
{
     var index:int;
     while ((index = sourceArray.indexOf(search)) >= 0)
     {
          sourceArray.splice(index,1);
     }
     return sourceArray;
}

то вы бы использовали такую ​​​​функцию:

myArray = removeSearchString(myArray, "duck");
person prototypical    schedule 26.03.2013

person    schedule
comment
это вопрос о массиве и сценарии действий, но не вопрос о лучшем алгоритме - person Ilya Zaytsev; 25.03.2013
comment
Я не делаю работы, о которых автор не просил, если у вас есть мнение, вы можете написать свой ответ - person Ilya Zaytsev; 25.03.2013
comment
Да, эти элементы являются строками, я забыл поставить кавычки, спасибо за внимание - только что исправил. Спасибо всем за ваши ответы. Попробую штуковину indexOf. - person ; 25.03.2013
comment
@PeterBeelich indexOf() вернет значение -1, если аргумент не может быть найден. Вы можете использовать сложные структуры а-ля while ((i=myArray.indexOf("duck"))>=0) myArray.splice(i,1);, чтобы удалить все вхождения утки, если вам это нужно. - person Vesper; 25.03.2013