Более эффективный способ удалить элемент из массива в Actionscript 3

У меня есть массив объектов. Каждый объект имеет свойство, названное именем. Я хочу эффективно удалить объект с конкретным именем от массива. Действительно ли это - Лучший способ?

  private function RemoveSpoke(Name:String):void {
    var Temp:Array=new Array;
    for each (var S:Object in Spokes) {
      if (S.Name!=Name) {
        Temp.push(S);
      }
    }
    Spokes=Temp;
  }
6
задан Patrick 26 May 2010 в 21:04
поделиться

8 ответов

Если вы готовы потратить немного памяти на таблицу поиска, это будет довольно быстро:

private function remove( data:Array, objectTable:Object, name:String):void {
var index:int = data.indexOf( objectTable[name] );
objectTable[name] = null;
data.splice( index, 1 );
}

Тест для этого выглядит так:

private function test():void{

var lookup:Object = {};
var Spokes:Array = [];
for ( var i:int = 0; i < 1000; i++ )
{
    var obj:Object = { name: (Math.random()*0xffffff).toString(16), someOtherProperty:"blah" };
    if ( lookup[ obj.name ] == null )
    {
        lookup[ obj.name ] = obj;
        Spokes.push( obj );
    }
}

var t:int = getTimer();
for ( var i:int = 0; i < 500; i++ )
{
    var test:Object = Spokes[int(Math.random()*Spokes.length)];
    remove(Spokes,lookup,test.name)
}
trace( getTimer() - t );

}

12
ответ дан 8 December 2019 в 03:26
поделиться

У меня нет данных для его резервного копирования, но я предполагаю, что array.filter может быть самым быстрым.

1
ответ дан 8 December 2019 в 03:26
поделиться

Вы также можете использовать ArrayCollection с filterFunction, чтобы получить представление о том же объекте Array

0
ответ дан 8 December 2019 в 03:26
поделиться

Самый быстрый способ будет следующим:

function remove(array: Array, name: String): void {
  var n: int = array.length
  while(--n > -1) {
    if(name == array[n].name) {
      array.splice(n, 1)
      return
    }
   }
}

remove([{name: "hi"}], "hi")

Вы также можете удалить оператор return, если хотите избавиться от всех элементов, соответствующих данному предикату.

5
ответ дан 8 December 2019 в 03:26
поделиться

Если вы не против использовать ArrayCollection, который является оберткой для класса Array, вы можете сделать что-то вроде этого:

private function RemoveSpoke(Name:String, Spokes:Array):Array{
  var ac:ArrayCollection = new ArrayCollection(Spokes);
  for (var i:int=0, imax:int=ac.length; i<imax; i++) {
    if (Spokes[i].hasOwnProperty("Name") && Spokes[i].Name === Name) {
      ac.removeItemAt(i);
      return ac.source;
    }
  }
  return ac.source;
}
0
ответ дан 8 December 2019 в 03:26
поделиться

Возможно, этот метод (оптимизированный метод сращивания CJ's) еще больше улучшит метод, предложенный Квазимондо:

http://cjcat.blogspot.com/ 2010/05/stardust-v11-with-fast-array-splicing_21.html

0
ответ дан 8 December 2019 в 03:26
поделиться

В общем случае вы должны предпочесть старый цикл for-loop, а не "for each" и "for each in", и использовать Vector, если ваши элементы имеют одинаковый тип. Если производительность действительно важна, вам следует рассмотреть возможность использования связного списка.

Посмотрите слайды Гранта Скиннера http://gskinner.com/talks/quick/ и блог Джексона Данстана для получения дополнительной информации об оптимизации.

1
ответ дан 8 December 2019 в 03:26
поделиться

Вот эффективная с точки зрения повторного использования функция, позволяющая делать больше, чем удаление элемента. Она возвращает индекс или -1, если элемент не найден.

function searchByProp(arr:Array, prop:String, value:Object): int
{
 var item:Object;
 var n: int = arr.length;
 for(var i:int=n;i>0;i--)
 {
  item = arr[i-1];
  if(item.hasOwnProperty(prop))
   if( value == item[prop] )
    return i-1;
 }
 return -1;
}
0
ответ дан 8 December 2019 в 03:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: