2009-09-11 7 views
4

this is from Adobe docs:Array.filter pour tester dynamiquement les valeurs

package { 
    import flash.display.Sprite; 
    public class Array_filter extends Sprite { 
     public function Array_filter() { 
      var employees:Array = new Array(); 
      employees.push({name:"Employee 1", manager:false}); 
      employees.push({name:"Employee 2", manager:true}); 
      employees.push({name:"Employee 3", manager:false}); 
      trace("Employees:"); 
      employees.forEach(traceEmployee); 

      var managers:Array = employees.filter(isManager); 
      trace("Managers:"); 
      managers.forEach(traceEmployee); 
     } 
     private function isManager(element:*, index:int, arr:Array):Boolean { 
      return (element.manager == true); 
     } 
     private function traceEmployee(element:*, index:int, arr:Array):void { 
      trace("\t" + element.name + ((element.manager) ? " (manager)" : "")); 
     } 
    } 
} 

Le problème est le procédé de filtrage de la classe Array. Cela fonctionne de cette façon: vous passez une fonction en tant qu'argument de filtre et un tableau est renvoyé en fonction de la fonction que vous transmettez. Le problème est qu'il semble que vous ne pouvez pas ajouter d'autres paramètres. Donc, si vous devez créer (par exemple à l'intérieur d'une boucle for) 4 tableaux du même tableau et que vous voulez utiliser la même fonction, vous ne pouvez tester que sur une propriété de la classe que vous avez précédemment définie sur la valeur que vous voulez tester .

Existe-t-il un autre moyen d'ajouter ce paramètre?

Répondre

0

Vous souhaitez utiliser quelque chose comme Delegates ou une fonction de liaison, ou des fermetures. En fonction de vos préférences de codage et de terminologie. L'idée derrière chacun d'eux est que vous créez un wrapper de fonction dynamique pour la fonction "filtre" de base. Ce wrapper aura accès à des paramètres supplémentaires que vous passez. Ainsi, la première fois que vous l'appelez, vous pourriez aller:

a.filter(Delegate.create(myFunc, param1)); 

et la prochaine fois:

a.filter(Delegate.create(myFunc, param2)); 

et vous fonctionnez aurait quelque chose comme ceci:

private function myFunc(item:*, index:Number, a:Array, param:Object=null):Boolean{} 

Un rapide une méthode sale est de simplement passer une fonction en ligne comme ceci:

a.filter(
    function(item:*, index:Number, a:Array):Boolean { 
    return myFunc(item,index,a,param1); 
    } 
); 

où param1 est passé en utilisant la fermeture créée par la définition de la fonction.

+0

Salut Glenn, et merci. Avons-nous des délégués dans AS3 aussi? Je n'ai pas pu les trouver ... –

+1

Les délégués ne font pas partie du langage AS3 en tant que classe native. Vous devez rouler le vôtre (ou trouver un échantillon en ligne). Faites juste une classe avec une fonction "create" statique qui retourne une autre fonction. Et la classe peut garder une trace de vos paramètres supplémentaires. – Glenn

+0

Salut Glenn, je pensais que peut-être cela peut être utile Function.apply –

3

Lors du filtrage par les propriétés d'objet variables dans un tableau, j'enveloppé le filtrage dans une autre fonction:

protected function FilterByProperty(input_array:Array, extra_testing:Object):Array 
{ 
    function FilterFunction(element:Object, index:int, array:Array):Boolean 
    { 
     return element.property == extra_testing; // Arbitrary test 
    } 

    return input_array.filter(FilterFunction); 
} 

var filtered_array:Array = FilterByProperty(unfiltered_array, test_property); 
2

Vous pouvez utiliser second paramètre de méthode filter() pour transmettre des données à filtrer fonction. Il sera disponible en tant que "cette" variable. Pour faire ce premier paramètre doit être une fermeture, pas une méthode de classe.

var array:Array = [...]; 
var params:Object = {"param1": value1, "param2": value2}; 

var filterFunction:Function = function(item:*, index:int, array:Array):Boolean { 
    var param1 = this["param1"]; 
    var param2 = this["param2"]; 
}; 

array.filter(filterFunction, params); 
Questions connexes