2010-03-14 8 views
13

Comme continuation de mon min/max à travers un tableau d'objets, je m'interrogeais sur les comparaisons de performance de filter vs map.Filtre Javascript vs problème de carte

J'ai donc mis en place un test sur les valeurs de mon code comme j'allais regarder les résultats dans FireBug.

Voici le code:

var _vec = this.vec; 
min_x = Math.min.apply(Math, _vec.filter(function(el){ return el["x"]; })); 
min_y = Math.min.apply(Math, _vec.map(function(el){ return el["x"]; })); 

La map version ped renvoie le résultat correct. Cependant, la version filter ed renvoie NaN. Rompre, passer à travers et enfin inspecter les résultats, il semblerait que la fonction interne renvoie la propriété x de _vec mais le tableau réel retourné de filter est le non filtré.

Je crois que mon utilisation de filter est correcte - quelqu'un d'autre peut-il voir mon problème?

Voici un test simple:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
<meta http-equiv="content-type" content="text/html; charset=utf-8" /> 
<title>S:GTC Map Test</title> 
</head> 
<body> 
<script type="text/javascript"> 
function vector(x,y,z) { this.x = x; this.y =y; this.z=z; } 
var vec = []; 
vec.push(new vector(1,1,1)); 
vec.push(new vector(2,2,2)); 
vec.push(new vector(2,3,3)); 
var _vec = vec; 
min_x = Math.min.apply(Math, _vec.filter(function(el){ return el["x"]; })); 
min_y = Math.min.apply(Math, _vec.map(function(el){ return el["x"]; })); 

document.write("<br>filter = " + min_x); 
document.write("<br>map = " + min_y); 
</script> 
</body> 
</html> 

Répondre

34

Non, la méthode filter ne retourne pas le tableau unfiletered. Il renvoie un tableau contenant les éléments où la fonction interne renvoie true.

Comme vous ne renvoyez pas de valeur booléenne à la fonction interne, la valeur est convertie en valeur booléenne. La référence d'objet est donc convertie en true. Ainsi, il retourne un nouveau tableau qui contient tous les éléments du tableau original. La méthode filter ne fait pas la même chose que la méthode map. La méthode map est utilisée pour convertir chaque élément d'un tableau, tandis que la méthode filter est utilisée pour sélectionner certains éléments d'un tableau. Comparer les performances entre les méthodes est discutable, car seul un d'entre eux fait ce que vous voulez faire.

+2

Ahh. Il semble que j'ai mal compris le fonctionnement du filtre. J'étais sous l'impression qu'il renvoyait un objet modifié à un tableau. –

4

Citation de:

JavaScript: La référence
par David Flanagan

carte ()

Le procédé map() passe chaque élément du tableau sur lequel il est invoqué à la fonction que vous spécifiez et renvoie un tableau contenant les valeurs renvoyées par cette fonction.

Par exemple:

a = [1, 2, 3]; 

b = a.map(function(x) { return x*x; }); // b is [1, 4, 9] 

La fonction que vous passez à la carte() est invoquée de la même manière en fonction passée à foreach(). Pour la méthode map(), cependant, la fonction que vous transmettez doit renvoyer une valeur. Notez que map() renvoie un nouveau tableau : il ne modifie pas le tableau sur lequel il est appelé. Si ce tableau est sparse, le tableau retourné sera éparpillé de la même manière: il aura la même longueur et les mêmes éléments manquants.

filtre()

Le procédé retourne un tableau contenant un sous-ensemble des éléments de la matrice sur lequel elle est appelée. La fonction que vous lui transmettez doit être predicate: une fonction qui renvoie true ou false. Le prédicat est invoqué comme pour forEach() et map(). Si la valeur de retour est true, ou une valeur qui convertit en true, alors l'élément transmis au prédicat est un membre du sous-ensemble et est ajouté au tableau que deviendra la valeur de retour.

Exemples:

a = [5, 4, 3, 2, 1]; 

smallvalues = a.filter(function(x) { return x < 3 }); // [2, 1] 

everyother = a.filter(function(x,i) { return i%2==0 }); // [5, 3, 1]