Более эффективный способ удаления элемента из массива в Actionscript 3 - PullRequest
6 голосов
/ 26 мая 2010

У меня есть массив объектов. Каждый объект имеет свойство с именем name. Я хочу эффективно удалить объект с определенным именем из массива. Это ЛУЧШИЙ способ?

  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;
  }

Ответы [ 9 ]

12 голосов
/ 27 мая 2010

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

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 );

}

10 голосов
/ 29 августа 2011

myArray.splice (myArray.indexOf (myInstance), 1);

5 голосов
/ 27 мая 2010

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

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, если хотите избавиться от всех элементов, соответствующих данному предикату.

1 голос
/ 27 мая 2010

В общем, вы должны предпочесть старый цикл for вместо «для каждого» и «для каждого входа» и использовать Vector, если ваши элементы относятся к одному типу. Если производительность действительно важна, вам следует рассмотреть возможность использования связанного списка.

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

1 голос
/ 27 мая 2010

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

0 голосов
/ 27 мая 2010

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

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

0 голосов
/ 27 мая 2010

Вот эффективная функция с точки зрения возможности повторного использования, позволяющая вам сделать больше, чем просто удалить элемент. Возвращает индекс или -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 голосов
/ 27 мая 2010

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

0 голосов
/ 26 мая 2010

Если вы не возражаете против использования 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;
}
...