2010-03-14 7 views
13

Jako kontynuację mojego min/max w całej tablicy obiektów zastanawiałem się nad porównaniami wydajności filtra z mapą.Filtr JavaScript vs problem z mapą

Tak więc przygotowałem test wartości w moim kodzie, tak jak miało to wyglądać w FireBug.

Jest to kod:

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"]; })); 

map wersja ped zwraca poprawny wynik. Jednak wersja filter ed zwraca NaN. Rozbijając go, przechodząc i ostatecznie sprawdzając wyniki, wydaje się, że funkcja wewnętrzna zwraca właściwość x z _vec, ale faktyczna tablica zwrócona z filter jest niefiltrowana _vec.

Wierzę, że moje użycie filter jest poprawne - czy ktoś inny może zobaczyć mój problem?

Oto prosty test:

<!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> 

Odpowiedz

34

Nie, metoda filter nie zwróci unfiletered tablicę. Zwraca tablicę zawierającą elementy, w których funkcja wewnętrzna zwraca wartość true.

Ponieważ nie zwracamy wartości boolowskiej z funkcji wewnętrznej, wartość jest konwertowana na wartość logiczną, więc odwołanie do obiektu jest konwertowane na wartość true. W ten sposób zwraca nową tablicę zawierającą wszystkie elementy z oryginalnej tablicy.

Metoda filter nie działa tak samo jak metoda . Metoda map służy do konwersji każdego elementu tablicy, a metoda filter służy do wybierania niektórych elementów tablicy. Porównywanie wydajności między metodami jest dyskusyjne, ponieważ tylko jeden z nich robi to, co chcesz robić.

+2

ach. Wygląda na to, że źle zrozumiałem, jak funkcjonuje filtr. Miałem wrażenie, że zwrócił zmodyfikowany obiekt do tablicy. –

4

Cytat z:

JavaScript: The Definitive Guide
David Flanagan

map()

Sposób map() przechodzi każdy element tablicy na której jest wywoływany do określonej funkcji i zwraca tablicę zawierającą wartości zwracane przez tę funkcję.

Na przykład:

a = [1, 2, 3]; 

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

Funkcję można przejść do map() jest wywoływana w taki sam sposób jak funkcji przekazany do foreach(). W przypadku metody map() funkcja, którą przekazujesz, powinna zwrócić wartość. Zwróć uwagę, że map() zwraca nową tablicę : nie modyfikuje ona tablicy, do której jest wywoływana. Jeśli ta tablica jest rzadka, zwrócona tablica będzie rozrzedzona w ten sam sposób: będzie ona mieć taką samą długość i te same brakujące elementy.

filtr()

Sposób powraca tablicę zawierającą podzbiór elementów tablicy na którym jest wywoływany. Funkcja, którą należy przekazać, powinna być predykatem : funkcja, która zwraca wartość true lub false. Predykat jest wywoływany podobnie jak dla forEach() i map(). Jeśli wartość zwracana jest prawdą, lub wartością, która przekształca się w wartość true, element przekazany do predykatu jest członkiem podzbioru i jest dodawany do tablicy, która stanie się wartością zwracaną przez tę wartość.

Przykłady:

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]